adaptivedemux2/downloadhelper: Remove return val for download_request_add_buffer()
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-good / ext / adaptivedemux2 / downloadrequest.c
1 /* GStreamer
2  * Copyright (C) 2011 Andoni Morales Alastruey <ylatuya@gmail.com>
3  * Copyright (C) 2021-2022 Jan Schmidt <jan@centricular.com>
4  *
5  * gstrequest.c:
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <glib.h>
27 #include <gst/base/gsttypefindhelper.h>
28 #include <gst/base/gstadapter.h>
29 #include "downloadrequest.h"
30
31 typedef struct _DownloadRequestPrivate DownloadRequestPrivate;
32
33 struct _DownloadRequestPrivate
34 {
35   DownloadRequest request;
36
37   GstBuffer *buffer;
38   GstCaps *caps;
39   GRecMutex lock;
40
41   DownloadRequestEventCallback completion_cb;
42   DownloadRequestEventCallback cancellation_cb;
43   DownloadRequestEventCallback error_cb;
44   DownloadRequestEventCallback progress_cb;
45   void *cb_data;
46 };
47
48 #define DOWNLOAD_REQUEST_PRIVATE(frag) ((DownloadRequestPrivate *)(frag))
49
50 static void download_request_free (DownloadRequest * request);
51
52 DownloadRequest *
53 download_request_new (void)
54 {
55   DownloadRequest *request =
56       (DownloadRequest *) g_slice_new0 (DownloadRequestPrivate);
57   DownloadRequestPrivate *priv = DOWNLOAD_REQUEST_PRIVATE (request);
58
59   g_atomic_int_set (&request->ref_count, 1);
60
61   g_rec_mutex_init (&priv->lock);
62
63   priv->buffer = NULL;
64
65   request->state = DOWNLOAD_REQUEST_STATE_UNSENT;
66   request->status_code = 0;
67
68   request->download_request_time = GST_CLOCK_TIME_NONE;
69   request->download_start_time = GST_CLOCK_TIME_NONE;
70   request->download_end_time = GST_CLOCK_TIME_NONE;
71   request->headers = NULL;
72
73   return (DownloadRequest *) (request);
74 }
75
76 DownloadRequest *
77 download_request_new_uri (const gchar * uri)
78 {
79   DownloadRequest *request = download_request_new ();
80
81   request->uri = g_strdup (uri);
82   request->range_start = 0;
83   request->range_end = -1;
84
85   return request;
86 }
87
88 DownloadRequest *
89 download_request_new_uri_range (const gchar * uri, gint64 range_start,
90     gint64 range_end)
91 {
92   DownloadRequest *request = download_request_new ();
93
94   request->uri = g_strdup (uri);
95   request->range_start = range_start;
96   request->range_end = range_end;
97
98   return request;
99 }
100
101 static void
102 download_request_free (DownloadRequest * request)
103 {
104   DownloadRequestPrivate *priv = DOWNLOAD_REQUEST_PRIVATE (request);
105
106   g_free (request->uri);
107   g_free (request->redirect_uri);
108   if (request->headers) {
109     gst_structure_free (request->headers);
110     request->headers = NULL;
111   }
112
113   if (priv->buffer != NULL) {
114     gst_buffer_unref (priv->buffer);
115     priv->buffer = NULL;
116   }
117
118   if (priv->caps != NULL) {
119     gst_caps_unref (priv->caps);
120     priv->caps = NULL;
121   }
122
123   g_rec_mutex_clear (&priv->lock);
124
125   g_slice_free1 (sizeof (DownloadRequestPrivate), priv);
126 }
127
128 void
129 download_request_set_callbacks (DownloadRequest * request,
130     DownloadRequestEventCallback on_completion,
131     DownloadRequestEventCallback on_error,
132     DownloadRequestEventCallback on_cancellation,
133     DownloadRequestEventCallback on_progress, void *cb_data)
134 {
135   DownloadRequestPrivate *priv = DOWNLOAD_REQUEST_PRIVATE (request);
136   g_rec_mutex_lock (&priv->lock);
137   priv->completion_cb = on_completion;
138   priv->error_cb = on_error;
139   priv->cancellation_cb = on_cancellation;
140   priv->progress_cb = on_progress;
141   priv->cb_data = cb_data;
142
143   request->send_progress = (on_progress != NULL);
144
145   g_rec_mutex_unlock (&priv->lock);
146 }
147
148 /* Called with request lock held */
149 void
150 download_request_despatch_progress (DownloadRequest * request)
151 {
152   DownloadRequestPrivate *priv = DOWNLOAD_REQUEST_PRIVATE (request);
153   if (priv->progress_cb)
154     priv->progress_cb (request, request->state, priv->cb_data);
155 }
156
157 /* Called with request lock held */
158 void
159 download_request_despatch_completion (DownloadRequest * request)
160 {
161   DownloadRequestPrivate *priv = DOWNLOAD_REQUEST_PRIVATE (request);
162   switch (request->state) {
163     case DOWNLOAD_REQUEST_STATE_UNSENT:
164       if (priv->cancellation_cb)
165         priv->cancellation_cb (request, request->state, priv->cb_data);
166       break;
167     case DOWNLOAD_REQUEST_STATE_COMPLETE:
168       if (priv->completion_cb)
169         priv->completion_cb (request, request->state, priv->cb_data);
170       break;
171     case DOWNLOAD_REQUEST_STATE_ERROR:
172       if (priv->error_cb)
173         priv->error_cb (request, request->state, priv->cb_data);
174       break;
175     default:
176       g_assert_not_reached ();
177   }
178 }
179
180
181 DownloadRequest *
182 download_request_ref (DownloadRequest * request)
183 {
184   g_return_val_if_fail (request != NULL, NULL);
185   g_atomic_int_inc (&request->ref_count);
186
187   return request;
188 }
189
190 void
191 download_request_unref (DownloadRequest * request)
192 {
193   g_return_if_fail (request != NULL);
194
195   if (g_atomic_int_dec_and_test (&request->ref_count)) {
196     download_request_free (request);
197   }
198 }
199
200 void
201 download_request_lock (DownloadRequest * request)
202 {
203   DownloadRequestPrivate *priv = DOWNLOAD_REQUEST_PRIVATE (request);
204   g_rec_mutex_lock (&priv->lock);
205 }
206
207 void
208 download_request_unlock (DownloadRequest * request)
209 {
210   DownloadRequestPrivate *priv = DOWNLOAD_REQUEST_PRIVATE (request);
211   g_rec_mutex_unlock (&priv->lock);
212 }
213
214 GstBuffer *
215 download_request_take_buffer (DownloadRequest * request)
216 {
217   DownloadRequestPrivate *priv = DOWNLOAD_REQUEST_PRIVATE (request);
218   GstBuffer *buffer = NULL;
219
220   g_return_val_if_fail (request != NULL, NULL);
221
222   g_rec_mutex_lock (&priv->lock);
223
224   if (request->state != DOWNLOAD_REQUEST_STATE_LOADING
225       && request->state != DOWNLOAD_REQUEST_STATE_COMPLETE) {
226     g_rec_mutex_unlock (&priv->lock);
227     return NULL;
228   }
229
230   buffer = priv->buffer;
231   priv->buffer = NULL;
232
233   g_rec_mutex_unlock (&priv->lock);
234
235   return buffer;
236 }
237
238 void
239 download_request_set_uri (DownloadRequest * request, const gchar * uri,
240     gint64 range_start, gint64 range_end)
241 {
242   DownloadRequestPrivate *priv = DOWNLOAD_REQUEST_PRIVATE (request);
243   g_rec_mutex_lock (&priv->lock);
244
245   g_assert (request->in_use == FALSE);
246
247   if (request->uri != uri) {
248     g_free (request->uri);
249     request->uri = g_strdup (uri);
250   }
251
252   g_free (request->redirect_uri);
253   request->redirect_uri = NULL;
254   request->redirect_permanent = FALSE;
255
256   request->range_start = range_start;
257   request->range_end = range_end;
258
259   g_rec_mutex_unlock (&priv->lock);
260 }
261
262 void
263 download_request_reset (DownloadRequest * request)
264 {
265   DownloadRequestPrivate *priv = DOWNLOAD_REQUEST_PRIVATE (request);
266
267   g_rec_mutex_lock (&priv->lock);
268   g_assert (request->in_use == FALSE);
269   request->state = DOWNLOAD_REQUEST_STATE_UNSENT;
270
271   if (request->headers) {
272     gst_structure_free (request->headers);
273     request->headers = NULL;
274   }
275
276   if (priv->buffer != NULL) {
277     gst_buffer_unref (priv->buffer);
278     priv->buffer = NULL;
279   }
280
281   if (priv->caps != NULL) {
282     gst_caps_unref (priv->caps);
283     priv->caps = NULL;
284   }
285
286   g_rec_mutex_unlock (&priv->lock);
287 }
288
289 /* Called when the request is submitted, to clear any settings from a previous
290  * download */
291 void
292 download_request_begin_download (DownloadRequest * request)
293 {
294   DownloadRequestPrivate *priv = DOWNLOAD_REQUEST_PRIVATE (request);
295
296   g_return_if_fail (request != NULL);
297
298   g_rec_mutex_lock (&priv->lock);
299
300   if (priv->buffer != NULL) {
301     gst_buffer_unref (priv->buffer);
302     priv->buffer = NULL;
303   }
304
305   if (request->headers) {
306     gst_structure_free (request->headers);
307     request->headers = NULL;
308   }
309
310   if (priv->caps != NULL) {
311     gst_caps_unref (priv->caps);
312     priv->caps = NULL;
313   }
314
315   request->content_length = 0;
316   request->content_received = 0;
317
318   request->download_request_time = GST_CLOCK_TIME_NONE;
319   request->download_start_time = GST_CLOCK_TIME_NONE;
320   request->download_end_time = GST_CLOCK_TIME_NONE;
321
322   g_rec_mutex_unlock (&priv->lock);
323 }
324
325 void
326 download_request_set_caps (DownloadRequest * request, GstCaps * caps)
327 {
328   DownloadRequestPrivate *priv = DOWNLOAD_REQUEST_PRIVATE (request);
329   g_return_if_fail (request != NULL);
330
331   g_rec_mutex_lock (&priv->lock);
332   gst_caps_replace (&priv->caps, caps);
333   g_rec_mutex_unlock (&priv->lock);
334 }
335
336 GstCaps *
337 download_request_get_caps (DownloadRequest * request)
338 {
339   DownloadRequestPrivate *priv = DOWNLOAD_REQUEST_PRIVATE (request);
340   GstCaps *caps;
341
342   g_return_val_if_fail (request != NULL, NULL);
343
344   if (request->state != DOWNLOAD_REQUEST_STATE_LOADING
345       && request->state != DOWNLOAD_REQUEST_STATE_COMPLETE)
346     return NULL;
347
348   g_rec_mutex_lock (&priv->lock);
349   if (priv->caps == NULL) {
350     guint64 offset, offset_end;
351
352     /* FIXME: This is currently necessary as typefinding only
353      * works with 0 offsets... need to find a better way to
354      * do that */
355     offset = GST_BUFFER_OFFSET (priv->buffer);
356     offset_end = GST_BUFFER_OFFSET_END (priv->buffer);
357     GST_BUFFER_OFFSET (priv->buffer) = GST_BUFFER_OFFSET_NONE;
358     GST_BUFFER_OFFSET_END (priv->buffer) = GST_BUFFER_OFFSET_NONE;
359     priv->caps = gst_type_find_helper_for_buffer (NULL, priv->buffer, NULL);
360     GST_BUFFER_OFFSET (priv->buffer) = offset;
361     GST_BUFFER_OFFSET_END (priv->buffer) = offset_end;
362   }
363
364   caps = gst_caps_ref (priv->caps);
365   g_rec_mutex_unlock (&priv->lock);
366
367   return caps;
368 }
369
370 void
371 download_request_add_buffer (DownloadRequest * request, GstBuffer * buffer)
372 {
373   DownloadRequestPrivate *priv = DOWNLOAD_REQUEST_PRIVATE (request);
374
375   g_return_if_fail (request != NULL);
376   g_return_if_fail (buffer != NULL);
377
378   if (request->state == DOWNLOAD_REQUEST_STATE_COMPLETE) {
379     GST_WARNING ("Download request is completed, could not add more buffers");
380     gst_buffer_unref (buffer);
381     return;
382   }
383
384   GST_DEBUG ("Adding new buffer %" GST_PTR_FORMAT " to the request data",
385       buffer);
386
387   request->content_received += gst_buffer_get_size (buffer);
388
389   /* We steal the buffers you pass in */
390   if (priv->buffer == NULL)
391     priv->buffer = buffer;
392   else
393     priv->buffer = gst_buffer_append (priv->buffer, buffer);
394 }