src->reduce_blocksize_count = 0;
src->increase_blocksize_count = 0;
+#ifdef TIZEN_FEATURE_SOUP_MODIFICATION
+ if (src->dash_oldest_segment) {
+ g_free (src->dash_oldest_segment);
+ src->dash_oldest_segment = NULL;
+ }
+ if (src->dash_newest_segment) {
+ g_free (src->dash_newest_segment);
+ src->dash_newest_segment = NULL;
+ }
+#endif
+
g_cancellable_reset (src->cancellable);
if (src->input_stream) {
g_object_unref (src->input_stream);
src->max_retries = DEFAULT_RETRIES;
src->method = DEFAULT_SOUP_METHOD;
src->minimum_blocksize = gst_base_src_get_blocksize (GST_BASE_SRC_CAST (src));
+#ifdef TIZEN_FEATURE_SOUP_MODIFICATION
+ src->dash_oldest_segment = NULL;
+ src->dash_newest_segment = NULL;
+#endif
proxy = g_getenv ("http_proxy");
if (!gst_soup_http_src_set_proxy (src, proxy)) {
GST_WARNING_OBJECT (src,
"The proxy in the http_proxy env var (\"%s\") cannot be parsed.",
proxy);
}
-
+#ifdef TIZEN_FEATURE_SOUP_MODIFICATION
+ src->cookie_jar = NULL;
+#endif
gst_base_src_set_automatic_eos (GST_BASE_SRC (src), FALSE);
gst_soup_http_src_reset (src);
break;
}
case PROP_COOKIES:
+#ifdef TIZEN_FEATURE_SOUP_MODIFICATION
+ {
+ char **array;
+ SoupURI *base_uri;
+ g_strfreev (src->cookies);
+ src->cookies = g_strdupv (g_value_get_boxed (value));
+
+ if (src->cookie_jar && ((array = src->cookies) != NULL)) {
+ base_uri = soup_uri_new (src->location);
+ GST_INFO_OBJECT (src, "request to set cookies...");
+ while (*array != NULL) {
+ soup_cookie_jar_add_cookie (src->cookie_jar,
+ soup_cookie_parse (*array++, base_uri));
+ }
+ soup_uri_free (base_uri);
+ } else {
+ GST_INFO_OBJECT (src, "set cookies after session creation");
+ }
+ }
+#else
g_strfreev (src->cookies);
src->cookies = g_strdupv (g_value_get_boxed (value));
+#endif
break;
case PROP_IS_LIVE:
gst_base_src_set_live (GST_BASE_SRC (src), g_value_get_boolean (value));
}
break;
case PROP_COOKIES:
- g_value_set_boxed (value, g_strdupv (src->cookies));
+#ifdef TIZEN_FEATURE_SOUP_MODIFICATION
+ {
+ GSList *cookie_list, *c;
+ gchar **cookies, **array;
+
+ cookies = NULL;
+ if ((src->cookie_jar) &&
+ ((cookie_list = soup_cookie_jar_all_cookies (src->cookie_jar)) != NULL)) {
+ cookies = g_new0 (gchar *, g_slist_length(cookie_list) + 1);
+ array = cookies;
+ for (c = cookie_list; c; c = c->next) {
+ *array++ = soup_cookie_to_set_cookie_header ((SoupCookie *)(c->data));
+ }
+ soup_cookies_free (cookie_list);
+ }
+ g_value_set_boxed (value, cookies);
+ }
+#else
+ g_value_set_boxed (value, g_strdupv (src->cookies));
+#endif
break;
case PROP_IS_LIVE:
g_value_set_boolean (value, gst_base_src_is_live (GST_BASE_SRC (src)));
gint rc;
soup_message_headers_remove (src->msg->request_headers, "Range");
- if (offset || stop_offset != -1) {
+
+/* This changes are needed to enable Seekable Contents from server.
+ We have observed that , for few specific networks ( VODAFONE ) , without theabove headers ,
+ Youtube is sending non-seekable contents to the Client. */
+#ifndef TIZEN_FEATURE_SOUP_MODIFICATION
+ if (offset || stop_offset != -1)
+#endif
+ {
if (stop_offset != -1) {
g_assert (offset != stop_offset);
stop_offset);
} else {
rc = g_snprintf (buf, sizeof (buf), "bytes=%" G_GUINT64_FORMAT "-",
- offset);
+ offset);
}
if (rc > sizeof (buf) || rc < 0)
return FALSE;
soup_message_headers_append (src->msg->request_headers, "Range", buf);
}
+
src->read_position = offset;
return TRUE;
}
soup_message_headers_append (src->msg->request_headers, field_name,
field_content);
+#ifdef TIZEN_FEATURE_SOUP_MODIFICATION
+ if (!g_ascii_strcasecmp(field_name, "Cookie")) {
+ SoupURI *uri = NULL;
+ SoupCookie *cookie_parsed = NULL;
+ gchar *saveptr = NULL;
+
+ if (strlen(field_content) > 0) {
+ gchar *tmp_field = NULL;
+
+ uri = soup_uri_new (src->location);
+
+ tmp_field = strtok_r (field_content, ";", &saveptr);
+
+ while (tmp_field != NULL) {
+ GST_DEBUG_OBJECT (src, "field_content = %s", tmp_field);
+
+ cookie_parsed = soup_cookie_parse(tmp_field, uri);
+ GST_DEBUG_OBJECT (src, "cookie parsed = %p", cookie_parsed);
+
+ if (src->cookie_jar)
+ soup_cookie_jar_add_cookie (src->cookie_jar, cookie_parsed);
+
+ tmp_field = strtok_r (NULL, ";", &saveptr);
+ }
+ soup_uri_free (uri);
+ }
+ }
+#endif
+
g_free (field_content);
return TRUE;
src->session =
soup_session_new_with_options (SOUP_SESSION_USER_AGENT,
src->user_agent, SOUP_SESSION_TIMEOUT, src->timeout,
- SOUP_SESSION_SSL_STRICT, src->ssl_strict,
- SOUP_SESSION_TLS_INTERACTION, src->tls_interaction, NULL);
+ SOUP_SESSION_SSL_STRICT, src->ssl_strict, NULL);
+// SOUP_SESSION_TLS_INTERACTION, src->tls_interaction, NULL);
} else {
src->session =
soup_session_new_with_options (SOUP_SESSION_PROXY_URI, src->proxy,
SOUP_SESSION_TIMEOUT, src->timeout,
SOUP_SESSION_SSL_STRICT, src->ssl_strict,
- SOUP_SESSION_USER_AGENT, src->user_agent,
- SOUP_SESSION_TLS_INTERACTION, src->tls_interaction, NULL);
+ SOUP_SESSION_USER_AGENT, src->user_agent, NULL);
+// SOUP_SESSION_TLS_INTERACTION, src->tls_interaction, NULL);
}
if (!src->session) {
return FALSE;
}
+#ifdef TIZEN_FEATURE_SOUP_MODIFICATION
+ {
+ char **array = NULL;
+ SoupURI *base_uri;
+ SoupCookie *soup_cookie = NULL;
+
+ soup_session_add_feature_by_type (src->session, SOUP_TYPE_COOKIE_JAR);
+ src->cookie_jar = SOUP_COOKIE_JAR (soup_session_get_feature (src->session, SOUP_TYPE_COOKIE_JAR));
+ if ((array = src->cookies) != NULL) {
+ base_uri = soup_uri_new (src->location);
+ while (*array != NULL) {
+ soup_cookie = soup_cookie_parse (*array++, base_uri);
+ if (soup_cookie != NULL) {
+ GST_INFO_OBJECT (src, "adding cookies..");
+ soup_cookie_jar_add_cookie (src->cookie_jar, soup_cookie);
+ }
+ }
+ soup_uri_free (base_uri);
+ }
+ }
+#endif
+
g_signal_connect (src->session, "authenticate",
G_CALLBACK (gst_soup_http_src_authenticate_cb), src);
}
if (src->session) {
+#ifdef TIZEN_FEATURE_SOUP_MODIFICATION
+/* When Playback is ongoing and Browser is moved to background ( Pressing Menu or Home Key ), The Session gets destroyed.
+ But the cookie_jar property remains unfreed. This results in garbage pointer and causes crash.
+ Removing the cookie_jar feature during close session of browser to handle the issue. */
+ GST_DEBUG_OBJECT (src, "Removing Cookie Jar instance");
+ soup_session_remove_feature_by_type(src->session, SOUP_TYPE_COOKIE_JAR);
+ src->cookie_jar = NULL;
+#endif
soup_session_abort (src->session);
g_object_unref (src->session);
src->session = NULL;
}
}
+#ifdef TIZEN_FEATURE_SOUP_MODIFICATION
+static void
+gst_soup_http_src_headers_foreach (const gchar * name, const gchar * val,
+ gpointer src)
+{
+ GST_INFO_OBJECT (src, " %s: %s", name, val);
+
+ if (g_ascii_strcasecmp (name, "Set-Cookie") == 0)
+ {
+ if (val)
+ {
+ gboolean bret = FALSE;
+ GstStructure *s = NULL;
+ GstSoupHTTPSrc * tmp = src;
+ SoupURI *uri;
+
+ uri = soup_uri_new (tmp->location);
+
+ /* post current bandwith & uri to application */
+ s = gst_structure_new ("cookies",
+ "updated-cookie", G_TYPE_STRING, val,
+ "updated-url", G_TYPE_STRING, tmp->location, NULL);
+ bret = gst_element_post_message (GST_ELEMENT_CAST (src), gst_message_new_element (GST_OBJECT_CAST (src), s));
+ soup_cookie_jar_set_cookie (tmp->cookie_jar, uri, val);
+ soup_uri_free (uri);
+
+ GST_INFO_OBJECT (src, "request url [%s], posted cookies [%s] msg and returned = %d", tmp->location, val, bret);
+ }
+ }
+ else if (g_ascii_strcasecmp (name, "Dash-Oldest-Segment") == 0)
+ {
+ if (val)
+ {
+ GstSoupHTTPSrc * tmp = src;
+ tmp->dash_oldest_segment = g_strdup (val);
+ GST_INFO_OBJECT (src, "Dash-Oldest-Segment set as %s ", tmp->dash_oldest_segment);
+ }
+ }
+ else if (g_ascii_strcasecmp (name, "Dash-Newest-Segment") == 0)
+ {
+ if (val)
+ {
+ GstSoupHTTPSrc * tmp = src;
+ tmp->dash_newest_segment = g_strdup (val);
+ GST_INFO_OBJECT (src, "Dash-Newest-Segment set as %s ", tmp->dash_newest_segment);
+ }
+ }
+}
+#endif
+
static GstFlowReturn
gst_soup_http_src_got_headers (GstSoupHTTPSrc * src, SoupMessage * msg)
{
GstEvent *http_headers_event;
GstStructure *http_headers, *headers;
const gchar *accept_ranges;
+#ifdef TIZEN_FEATURE_SOUP_MODIFICATION
+ gint64 start = 0, stop = 0, total = 0;
+#endif
- GST_INFO_OBJECT (src, "got headers");
-
+ GST_INFO_OBJECT (src, "got headers : %d", msg->status_code);
+#ifdef TIZEN_FEATURE_SOUP_MODIFICATION
+ soup_message_headers_foreach (msg->response_headers,
+ gst_soup_http_src_headers_foreach, src);
+#endif
if (msg->status_code == SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED &&
src->proxy_id && src->proxy_pw) {
/* wait for authenticate callback */
/* Parse Content-Length. */
if (soup_message_headers_get_encoding (msg->response_headers) ==
SOUP_ENCODING_CONTENT_LENGTH) {
- newsize = src->request_position +
- soup_message_headers_get_content_length (msg->response_headers);
+#ifdef TIZEN_FEATURE_SOUP_MODIFICATION
+ if (msg->status_code == SOUP_STATUS_PARTIAL_CONTENT) {
+ newsize = src->request_position +
+ soup_message_headers_get_content_length (msg->response_headers);
+ } else {
+ if (soup_message_headers_get_content_range(msg->response_headers, &start, &stop, &total) && (total > 0)) {
+ GST_DEBUG_OBJECT (src, "get range header : %" G_GINT64_FORMAT
+ "~%" G_GINT64_FORMAT"/%"G_GINT64_FORMAT, start, stop, total);
+ newsize = (guint64)total;
+ } else {
+ if ((src->have_size) && (src->content_size <= src->request_position)) {
+ newsize = src->content_size;
+ } else {
+ newsize = soup_message_headers_get_content_length (msg->response_headers);
+ }
+ }
+ }
+#else
+ newsize = src->request_position +
+ soup_message_headers_get_content_length (msg->response_headers);
+#endif
if (!src->have_size || (src->content_size != newsize)) {
src->content_size = newsize;
src->have_size = TRUE;
if (g_ascii_strcasecmp (accept_ranges, "none") == 0)
src->seekable = FALSE;
}
+#ifdef TIZEN_FEATURE_SOUP_MODIFICATION
+ /* The Range request header is always included.
+ * @ref gst_soup_http_src_add_range_header() */
+ else if ((msg->status_code == SOUP_STATUS_OK) &&
+ (soup_message_headers_get_content_range(msg->response_headers, &start, &stop, &total) == FALSE)) {
+ GST_DEBUG_OBJECT (src, "there is no accept range header");
+ src->seekable = FALSE;
+ }
+#endif
/* Icecast stuff */
tag_list = gst_tag_list_new_empty ();
/* when content_size is unknown and we have just finished receiving
* a body message, requests that go beyond the content limits will result
* in an error. Here we convert those to EOS */
+#ifdef TIZEN_FEATURE_SOUP_MODIFICATION
+ if (msg->status_code == SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE &&
+ ((src->have_body && !src->have_size) ||
+ (src->have_size && src->request_position >= src->content_size))) {
+ GST_DEBUG_OBJECT (src, "Requested range out of limits and received full "
+ "body, returning EOS");
+ return GST_FLOW_EOS;
+ }
+#else
if (msg->status_code == SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE &&
src->have_body && !src->have_size) {
GST_DEBUG_OBJECT (src, "Requested range out of limits and received full "
"body, returning EOS");
return GST_FLOW_EOS;
}
+#endif
/* FIXME: reason_phrase is not translated and not suitable for user
* error dialog according to libsoup documentation.
soup_message_headers_append (src->msg->request_headers, "icy-metadata",
"1");
}
+
+#ifdef TIZEN_FEATURE_SOUP_MODIFICATION
+/* This changes are needed to enable Seekable Contents from server.
+ We have observed that , for few specific networks ( VODAFONE ) , without theabove headers ,
+ Youtube is sending non-seekable contents to the Client. */
+ soup_message_headers_append (src->msg->request_headers, "Accept-Ranges","bytes");
+
+ if (src->cookie_jar) {
+ GSList *cookie_list, *c;
+ gchar *header;
+
+ SoupURI *uri = NULL;
+ SoupCookie *cookie;
+ uri = soup_uri_new (src->location);
+
+ if ((cookie_list = soup_cookie_jar_all_cookies (src->cookie_jar)) != NULL) {
+ for (c = cookie_list; c; c = c->next) {
+ cookie = (SoupCookie *)c->data;
+ if (soup_cookie_applies_to_uri(cookie, uri)) {
+ header = soup_cookie_to_cookie_header (cookie);
+ soup_message_headers_append (src->msg->request_headers, "Cookie", header);
+ g_free (header);
+ }
+ }
+ }
+ soup_cookies_free (cookie_list);
+ soup_uri_free (uri);
+ }
+#else
if (src->cookies) {
gchar **cookie;
*cookie);
}
}
+#endif
soup_message_set_flags (src->msg, SOUP_MESSAGE_OVERWRITE_CHUNKS |
(src->automatic_redirect ? 0 : SOUP_MESSAGE_NO_REDIRECT));
gst_soup_http_src_add_extra_headers (src);
+#ifdef TIZEN_FEATURE_SOUP_MODIFICATION
+ soup_message_headers_foreach (src->msg->request_headers,
+ gst_soup_http_src_headers_foreach, src);
+#endif
+
return TRUE;
}
ret = gst_soup_http_src_send_message (src);
/* Check if Range header was respected. */
+#ifdef TIZEN_FEATURE_SOUP_MODIFICATION
+ if (ret == GST_FLOW_OK && src->request_position > 0 &&
+ (src->msg->status_code != SOUP_STATUS_PARTIAL_CONTENT) &&
+ (src->request_position < src->content_size)) {
+#else
if (ret == GST_FLOW_OK && src->request_position > 0 &&
src->msg->status_code != SOUP_STATUS_PARTIAL_CONTENT) {
+#endif
src->seekable = FALSE;
GST_ELEMENT_ERROR_WITH_DETAILS (src, RESOURCE, SEEK,
(_("Server does not support seeking.")),
GST_DEBUG_OBJECT (src, "start(\"%s\")", src->location);
+#ifdef TIZEN_FEATURE_SOUP_MODIFICATION
+ if (src->dash_oldest_segment) {
+ g_free (src->dash_oldest_segment);
+ src->dash_oldest_segment = NULL;
+ }
+ if (src->dash_newest_segment) {
+ g_free (src->dash_newest_segment);
+ src->dash_newest_segment = NULL;
+ }
+#endif
return gst_soup_http_src_session_open (src);
}
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_SCHEDULING:
+
gst_query_parse_scheduling (query, &flags, &minsize, &maxsize, &align);
flags |= GST_SCHEDULING_FLAG_BANDWIDTH_LIMITED;
+
+#ifdef TIZEN_FEATURE_SOUP_MODIFICATION
+ if (gst_soup_http_src_is_seekable(bsrc)) {
+ GST_DEBUG_OBJECT (src, "set seekable flag");
+ flags |= GST_SCHEDULING_FLAG_SEEKABLE;
+ }
+#endif
gst_query_set_scheduling (query, flags, minsize, maxsize, align);
+
break;
default:
break;