mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-22 23:28:16 +00:00
curlbasesink: Add curl seek callback
Adding functionality to handle SEEK_SET enables rewinding of sent data. In the HTTP case, this happens after an HTTP 401 has been received from the other end. This will result in the sent data being resent. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1616>
This commit is contained in:
parent
97e648a738
commit
9ded00bcf0
1 changed files with 56 additions and 0 deletions
|
@ -121,6 +121,8 @@ static size_t gst_curl_base_sink_transfer_read_cb (void *ptr, size_t size,
|
|||
size_t nmemb, void *stream);
|
||||
static size_t gst_curl_base_sink_transfer_write_cb (void *ptr, size_t size,
|
||||
size_t nmemb, void *stream);
|
||||
static int gst_curl_base_sink_transfer_seek_cb (void *user_p, curl_off_t offset,
|
||||
int origin);
|
||||
static size_t gst_curl_base_sink_transfer_data_buffer (GstCurlBaseSink * sink,
|
||||
void *curl_ptr, size_t block_size, guint * last_chunk);
|
||||
#ifndef GST_DISABLE_GST_DEBUG
|
||||
|
@ -705,6 +707,21 @@ gst_curl_base_sink_transfer_set_common_options_unlocked (GstCurlBaseSink * sink)
|
|||
curl_easy_strerror (res));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
res = curl_easy_setopt (sink->curl, CURLOPT_SEEKDATA, sink);
|
||||
if (res != CURLE_OK) {
|
||||
sink->error = g_strdup_printf ("failed to set seek user data: %s",
|
||||
curl_easy_strerror (res));
|
||||
return FALSE;
|
||||
}
|
||||
res = curl_easy_setopt (sink->curl, CURLOPT_SEEKFUNCTION,
|
||||
gst_curl_base_sink_transfer_seek_cb);
|
||||
if (res != CURLE_OK) {
|
||||
sink->error = g_strdup_printf ("failed to set seek function: %s",
|
||||
curl_easy_strerror (res));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Time out in case transfer speed in bytes per second stay below
|
||||
* CURLOPT_LOW_SPEED_LIMIT during CURLOPT_LOW_SPEED_TIME */
|
||||
res = curl_easy_setopt (sink->curl, CURLOPT_LOW_SPEED_LIMIT, 1L);
|
||||
|
@ -883,6 +900,45 @@ gst_curl_base_sink_transfer_write_cb (void G_GNUC_UNUSED * ptr, size_t size,
|
|||
return realsize;
|
||||
}
|
||||
|
||||
static int
|
||||
gst_curl_base_sink_transfer_seek_cb (void *stream, curl_off_t offset,
|
||||
int origin)
|
||||
{
|
||||
GstCurlBaseSink *sink;
|
||||
curl_off_t buf_size;
|
||||
|
||||
/*
|
||||
* Origin is SEEK_SET, SEEK_CUR or SEEK_END,
|
||||
* libcurl currently only passes SEEK_SET.
|
||||
*/
|
||||
|
||||
sink = (GstCurlBaseSink *) stream;
|
||||
|
||||
GST_OBJECT_LOCK (sink);
|
||||
buf_size = sink->transfer_buf->offset + sink->transfer_buf->len;
|
||||
|
||||
switch (origin) {
|
||||
case SEEK_SET:
|
||||
if ((0 <= offset) && (offset <= buf_size)) {
|
||||
sink->transfer_buf->offset = offset;
|
||||
sink->transfer_buf->len = buf_size - offset;
|
||||
} else {
|
||||
GST_OBJECT_UNLOCK (sink);
|
||||
return CURL_SEEKFUNC_FAIL;
|
||||
}
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
case SEEK_END:
|
||||
default:
|
||||
GST_OBJECT_UNLOCK (sink);
|
||||
return CURL_SEEKFUNC_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
GST_OBJECT_UNLOCK (sink);
|
||||
return CURL_SEEKFUNC_OK;
|
||||
}
|
||||
|
||||
CURLcode
|
||||
gst_curl_base_sink_transfer_check (GstCurlBaseSink * sink)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue