Commit 7b2a584d authored by Guillaume Desmottes's avatar Guillaume Desmottes

move NPT parsing code to util.c

This will allow this function to be properly tested as it's not static any
more.
parent 3bcf8d0f
......@@ -18,7 +18,11 @@ plugin_LTLIBRARIES = src/libgstdlnasrc.la
##############################################################################
# sources used to compile this plug-in
src_libgstdlnasrc_la_SOURCES = src/gstdlnasrc.c src/gstdlnasrc.h
src_libgstdlnasrc_la_SOURCES = \
src/gstdlnasrc.c \
src/gstdlnasrc.h \
src/util.c \
src/util.h
# compiler and linker flags used to compile this plugin, set in configure.ac
src_libgstdlnasrc_la_CFLAGS = $(GST_CFLAGS) $(SOUP_CFLAGS)
......@@ -28,4 +32,6 @@ src_libgstdlnasrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
src_libgstdlnasrc_la_LIBTOOLFLAGS = --tag=disable-static
# headers we need but don't want installed
noinst_HEADERS = src/gstdlnasrc.h
\ No newline at end of file
noinst_HEADERS = \
src/gstdlnasrc.h \
src/util.h
......@@ -37,6 +37,7 @@
#include <glib-object.h>
#include "gstdlnasrc.h"
#include "util.h"
enum
{
......@@ -324,11 +325,6 @@ static gboolean dlna_src_parse_byte_range (GstDlnaSrc * dlna_src,
const gchar * field_str, gint header_idx, guint64 * start_byte,
guint64 * end_byte, guint64 * total_bytes);
static gboolean
dlna_src_parse_npt_range (GstDlnaSrc * dlna_src, const gchar * npt_str,
gchar ** start_str, gchar ** stop_str, gchar ** total_str,
guint64 * start, guint64 * stop, guint64 * total);
static gboolean dlna_src_is_change_valid (GstDlnaSrc * dlna_src, gfloat rate,
GstFormat format, guint64 start,
GstSeekType start_type, guint64 stop, GstSeekType stop_type);
......@@ -339,9 +335,6 @@ static gboolean dlna_src_adjust_http_src_headers (GstDlnaSrc * dlna_src,
gfloat rate, GstFormat format, guint64 start, guint64 stop,
guint32 new_seqnum);
static gboolean dlna_src_npt_to_nanos (GstDlnaSrc * dlna_src, gchar * string,
guint64 * media_time_nanos);
static gboolean
dlna_src_convert_bytes_to_npt_nanos (GstDlnaSrc * dlna_src, guint64 bytes,
guint64 * npt_nanos);
......@@ -2687,91 +2680,6 @@ dlna_src_parse_byte_range (GstDlnaSrc * dlna_src,
return TRUE;
}
/**
* Parse the npt (normal play time) range which may be contained in the following headers:
*
* TimeSeekRange.dlna.org : npt=335.1-336.1/40445.4 bytes=1539686400-1540210688/304857907200
*
* availableSeekRange.dlna.org: 0 npt=0:00:00.000-0:00:48.716 bytes=0-5219255 cleartextbytes=0-5219255
*
* @param dlna_src this element instance
* @param field_str string containing HEAD response field header and value
* @param start_str starting time in string form read from header response field
* @param stop_str end time in string form read from header response field
* @param total_str total time in string form read from header response field
* @param start starting time in nanoseconds converted from string representation
* @param stop end time in nanoseconds converted from string representation
* @param total total time in nanoseconds converted from string representation
*
* @return returns TRUE
*/
static gboolean
dlna_src_parse_npt_range (GstDlnaSrc * dlna_src, const gchar * field_str,
gchar ** start_str, gchar ** stop_str, gchar ** total_str,
guint64 * start, guint64 * stop, guint64 * total)
{
gchar *header = NULL;
gchar *header_value = NULL;
gint ret_code = 0;
gchar tmp1[32] = { 0 };
gchar tmp2[32] = { 0 };
gchar tmp3[32] = { 0 };
/* Extract NPT portion of header value */
header =
strstr (g_ascii_strup (field_str, strlen (field_str)),
RANGE_HEADERS[HEADER_INDEX_NPT]);
if (header)
header_value = strstr (header, "=");
if (header_value)
header_value++;
else {
GST_WARNING_OBJECT (dlna_src,
"Problems parsing npt from HEAD response field header value: %s",
field_str);
return FALSE;
}
/* Determine if npt string includes total */
if (strstr (header_value, "/")) {
/* Extract start and end and total NPT */
if ((ret_code =
sscanf (header_value, "%31[^-]-%31[^/]/%31s %*s", tmp1, tmp2,
tmp3)) != 3) {
GST_WARNING_OBJECT (dlna_src,
"Problems parsing NPT from HEAD response field header %s, value: %s, retcode: %d, tmp: %s, %s, %s",
field_str, header_value, ret_code, tmp1, tmp2, tmp3);
return FALSE;
}
g_free (*total_str);
*total_str = g_strdup (tmp3);
if (strcmp (*total_str, "*") != 0)
if (!dlna_src_npt_to_nanos (dlna_src, *total_str, total))
return FALSE;
} else {
/* Extract start and end (there is no total) NPT */
if ((ret_code = sscanf (header_value, "%31[^-]-%31s %*s", tmp1, tmp2)) != 2) {
GST_WARNING_OBJECT (dlna_src,
"Problems parsing NPT from HEAD response field header %s, value: %s, retcode: %d, tmp: %s, %s",
field_str, header_value, ret_code, tmp1, tmp2);
return FALSE;
}
}
g_free (*start_str);
*start_str = g_strdup (tmp1);
if (!dlna_src_npt_to_nanos (dlna_src, *start_str, start))
return FALSE;
g_free (*stop_str);
*stop_str = g_strdup (tmp2);
if (!dlna_src_npt_to_nanos (dlna_src, *stop_str, stop))
return FALSE;
return TRUE;
}
/**
* Extract values from content features header in HEAD Response
*
......@@ -3750,59 +3658,6 @@ overflow:
return FALSE;
}
/**
* Convert supplied string which represents normal play time (npt) into
* nanoseconds. The format of NPT is as follows:
*
* npt time = npt sec | npt hhmmss
*
* npt sec = 1*DIGIT [ "." 1*3DIGIT ]
* npthhmmss = npthh":"nptmm":"nptss["."1*3DIGIT]
* npthh = 1*DIGIT ; any positive number
* nptmm = 1*2DIGIT ; 0-59
* nptss = 1*2DIGIT ; 0-59
*
* @param dlna_src this element, needed for logging
* @param string normal play time string to convert
* @param media_time_nanos npt string value converted into nanoseconds
*
* @return true if no problems encountered, false otherwise
*/
static gboolean
dlna_src_npt_to_nanos (GstDlnaSrc * dlna_src, gchar * string,
guint64 * media_time_nanos)
{
gboolean ret = FALSE;
guint hours = 0;
guint mins = 0;
float secs = 0.;
if (sscanf (string, "%u:%u:%f", &hours, &mins, &secs) == 3) {
/* Long form */
*media_time_nanos =
((hours * 60 * 60 * 1000) + (mins * 60 * 1000) +
(secs * 1000)) * 1000000L;
ret = TRUE;
GST_LOG_OBJECT (dlna_src,
"Convert npt str %s hr=%d:mn=%d:s=%f into nanosecs: %"
G_GUINT64_FORMAT, string, hours, mins, secs, *media_time_nanos);
} else if (sscanf (string, "%f", &secs) == 1) {
/* Short form */
*media_time_nanos = (secs * 1000) * 1000000L;
ret = TRUE;
GST_LOG_OBJECT (dlna_src,
"Convert npt str %s secs=%f into nanosecs: %"
G_GUINT64_FORMAT, string, secs, *media_time_nanos);
} else {
GST_ERROR_OBJECT (dlna_src,
"Problems converting npt str into nanosecs: %s", string);
}
return ret;
}
/**
* Formats given nanoseconds into string which represents normal play time (npt).
* The format of NPT is as follows:
......@@ -3831,7 +3686,6 @@ dlna_src_nanos_to_npt (GstDlnaSrc * dlna_src, guint64 media_time_nanos,
g_string_append_printf (npt_str, "%d:%02d:%02.3f", hours, minutes, seconds);
}
/* entry point to initialize the plug-in
* initialize the plug-in itself
* register the element factories and other features
......
/* Copyright (C) 2013 Cable Television Laboratories, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
* IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CABLE TELEVISION LABS INC. OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include <stdio.h>
#include <string.h>
#include "util.h"
/**
* Convert supplied string which represents normal play time (npt) into
* nanoseconds. The format of NPT is as follows:
*
* npt time = npt sec | npt hhmmss
*
* npt sec = 1*DIGIT [ "." 1*3DIGIT ]
* npthhmmss = npthh":"nptmm":"nptss["."1*3DIGIT]
* npthh = 1*DIGIT ; any positive number
* nptmm = 1*2DIGIT ; 0-59
* nptss = 1*2DIGIT ; 0-59
*
* @param dlna_src this element, needed for logging
* @param string normal play time string to convert
* @param media_time_nanos npt string value converted into nanoseconds
*
* @return true if no problems encountered, false otherwise
*/
static gboolean
dlna_src_npt_to_nanos (GstDlnaSrc * dlna_src, gchar * string,
guint64 * media_time_nanos)
{
gboolean ret = FALSE;
guint hours = 0;
guint mins = 0;
float secs = 0.;
if (sscanf (string, "%u:%u:%f", &hours, &mins, &secs) == 3) {
/* Long form */
*media_time_nanos =
((hours * 60 * 60 * 1000) + (mins * 60 * 1000) +
(secs * 1000)) * 1000000L;
ret = TRUE;
GST_LOG_OBJECT (dlna_src,
"Convert npt str %s hr=%d:mn=%d:s=%f into nanosecs: %"
G_GUINT64_FORMAT, string, hours, mins, secs, *media_time_nanos);
} else if (sscanf (string, "%f", &secs) == 1) {
/* Short form */
*media_time_nanos = (secs * 1000) * 1000000L;
ret = TRUE;
GST_LOG_OBJECT (dlna_src,
"Convert npt str %s secs=%f into nanosecs: %"
G_GUINT64_FORMAT, string, secs, *media_time_nanos);
} else {
GST_ERROR_OBJECT (dlna_src,
"Problems converting npt str into nanosecs: %s", string);
}
return ret;
}
/**
* Parse the npt (normal play time) range which may be contained in the following headers:
*
* TimeSeekRange.dlna.org : npt=335.1-336.1/40445.4 bytes=1539686400-1540210688/304857907200
*
* availableSeekRange.dlna.org: 0 npt=0:00:00.000-0:00:48.716 bytes=0-5219255 cleartextbytes=0-5219255
*
* @param dlna_src this element instance
* @param field_str string containing HEAD response field header and value
* @param start_str starting time in string form read from header response field
* @param stop_str end time in string form read from header response field
* @param total_str total time in string form read from header response field
* @param start starting time in nanoseconds converted from string representation
* @param stop end time in nanoseconds converted from string representation
* @param total total time in nanoseconds converted from string representation
*
* @return returns TRUE
*/
gboolean
dlna_src_parse_npt_range (GstDlnaSrc * dlna_src, const gchar * field_str,
gchar ** start_str, gchar ** stop_str, gchar ** total_str,
guint64 * start, guint64 * stop, guint64 * total)
{
gchar *header = NULL;
gchar *header_value = NULL;
gint ret_code = 0;
gchar tmp1[32] = { 0 };
gchar tmp2[32] = { 0 };
gchar tmp3[32] = { 0 };
/* Extract NPT portion of header value */
header =
strstr (g_ascii_strup (field_str, strlen (field_str)), "NPT");
if (header)
header_value = strstr (header, "=");
if (header_value)
header_value++;
else {
GST_WARNING_OBJECT (dlna_src,
"Problems parsing npt from HEAD response field header value: %s",
field_str);
return FALSE;
}
/* Determine if npt string includes total */
if (strstr (header_value, "/")) {
/* Extract start and end and total NPT */
if ((ret_code =
sscanf (header_value, "%31[^-]-%31[^/]/%31s %*s", tmp1, tmp2,
tmp3)) != 3) {
GST_WARNING_OBJECT (dlna_src,
"Problems parsing NPT from HEAD response field header %s, value: %s, retcode: %d, tmp: %s, %s, %s",
field_str, header_value, ret_code, tmp1, tmp2, tmp3);
return FALSE;
}
g_free (*total_str);
*total_str = g_strdup (tmp3);
if (strcmp (*total_str, "*") != 0)
if (!dlna_src_npt_to_nanos (dlna_src, *total_str, total))
return FALSE;
} else {
/* Extract start and end (there is no total) NPT */
if ((ret_code = sscanf (header_value, "%31[^-]-%31s %*s", tmp1, tmp2)) != 2) {
GST_WARNING_OBJECT (dlna_src,
"Problems parsing NPT from HEAD response field header %s, value: %s, retcode: %d, tmp: %s, %s",
field_str, header_value, ret_code, tmp1, tmp2);
return FALSE;
}
}
g_free (*start_str);
*start_str = g_strdup (tmp1);
if (!dlna_src_npt_to_nanos (dlna_src, *start_str, start))
return FALSE;
g_free (*stop_str);
*stop_str = g_strdup (tmp2);
if (!dlna_src_npt_to_nanos (dlna_src, *stop_str, stop))
return FALSE;
return TRUE;
}
/* Copyright (C) 2013 Cable Television Laboratories, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
* IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CABLE TELEVISION LABS INC. OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __GST_DLNA_SRC_UTIL_H__
#define __GST_DLNA_SRC_UTIL_H__
#include "gstdlnasrc.h"
gboolean dlna_src_parse_npt_range (GstDlnaSrc * dlna_src,
const gchar * field_str, gchar ** start_str, gchar ** stop_str,
gchar ** total_str, guint64 * start, guint64 * stop, guint64 * total);
#endif /* __GST_DLNA_SRC_UTIL_H__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment