From 940811d593bae34fc4da8b909b75ee590880e225 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Fri, 14 Oct 2022 06:22:35 +1100 Subject: [PATCH] adaptivedemux2/downloadrequest: Add new methods Add download_request_take_buffer_range() and download_request_get_bytes_available() methods. download_request_take_buffer_range() takes bytes from the front of the request that satisfy the requested start/end byterange, and puts any remaining bytes back into the DownloadRequest Part-of: --- .../ext/adaptivedemux2/downloadrequest.c | 72 +++++++++++++++++++ .../ext/adaptivedemux2/downloadrequest.h | 2 + 2 files changed, 74 insertions(+) diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/downloadrequest.c b/subprojects/gst-plugins-good/ext/adaptivedemux2/downloadrequest.c index 496325111b..62454c8ecc 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/downloadrequest.c +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/downloadrequest.c @@ -235,6 +235,78 @@ download_request_take_buffer (DownloadRequest * request) return buffer; } +GstBuffer * +download_request_take_buffer_range (DownloadRequest * request, + gint64 target_range_start, gint64 target_range_end) +{ + DownloadRequestPrivate *priv = DOWNLOAD_REQUEST_PRIVATE (request); + GstBuffer *buffer = NULL; + GstBuffer *input_buffer = NULL; + + g_return_val_if_fail (request != NULL, NULL); + + g_rec_mutex_lock (&priv->lock); + + if (request->state != DOWNLOAD_REQUEST_STATE_LOADING + && request->state != DOWNLOAD_REQUEST_STATE_COMPLETE) { + g_rec_mutex_unlock (&priv->lock); + return NULL; + } + + input_buffer = priv->buffer; + priv->buffer = NULL; + if (input_buffer == NULL) + goto out; + + /* Figure out how much of the available data (if any) belongs to + * the target range */ + gint64 avail_start = GST_BUFFER_OFFSET (input_buffer); + gint64 avail_end = avail_start + gst_buffer_get_size (input_buffer) - 1; + + if (target_range_start <= avail_end) { + /* There's at least 1 byte available that belongs to this target request, but + * does this buffer need splitting in two? */ + if (target_range_end != -1 && target_range_end < avail_end) { + /* Yes, it does. Cut off the front of the buffer */ + buffer = + gst_buffer_copy_region (input_buffer, GST_BUFFER_COPY_MEMORY, 0, + target_range_end - avail_start); + GST_BUFFER_OFFSET (buffer) = GST_BUFFER_OFFSET (input_buffer); + + /* Put the rest of the buffer back */ + priv->buffer = + gst_buffer_copy_region (input_buffer, GST_BUFFER_COPY_MEMORY, + target_range_end - avail_start, -1); + + /* Release the original buffer. The sub-buffers are holding their own refs as needed */ + gst_buffer_unref (input_buffer); + } else { + /* No, return the entire buffer */ + buffer = input_buffer; + } + } + +out: + g_rec_mutex_unlock (&priv->lock); + return buffer; +} + +guint64 +download_request_get_bytes_available (DownloadRequest * request) +{ + DownloadRequestPrivate *priv = DOWNLOAD_REQUEST_PRIVATE (request); + guint64 ret = 0; + + g_rec_mutex_lock (&priv->lock); + + if (priv->buffer != NULL) + ret = gst_buffer_get_size (priv->buffer); + + g_rec_mutex_unlock (&priv->lock); + + return ret; +} + void download_request_set_uri (DownloadRequest * request, const gchar * uri, gint64 range_start, gint64 range_end) diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/downloadrequest.h b/subprojects/gst-plugins-good/ext/adaptivedemux2/downloadrequest.h index b814d921b3..13827d6fbf 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/downloadrequest.h +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/downloadrequest.h @@ -85,6 +85,8 @@ GstCaps * download_request_get_caps (DownloadRequest * request); void download_request_add_buffer (DownloadRequest *request, GstBuffer *buffer); GstBuffer * download_request_take_buffer (DownloadRequest *request); +GstBuffer * download_request_take_buffer_range (DownloadRequest *request, gint64 range_start, gint64 range_end); +guint64 download_request_get_bytes_available (DownloadRequest *request); DownloadRequest * download_request_new (void); DownloadRequest * download_request_new_uri (const gchar * uri);