rtspsrc: fix range parsing

Fix parsing of the range headers.
This commit is contained in:
Wim Taymans 2009-03-05 14:08:14 +01:00
parent e4b8c514cc
commit 636cd65ebf
2 changed files with 74 additions and 46 deletions

View file

@ -93,7 +93,6 @@
#include <gst/sdp/gstsdpmessage.h> #include <gst/sdp/gstsdpmessage.h>
#include <gst/rtp/gstrtppayloads.h> #include <gst/rtp/gstrtppayloads.h>
#include <gst/rtsp/gstrtsprange.h>
#include "gstrtspsrc.h" #include "gstrtspsrc.h"
@ -405,7 +404,6 @@ gst_rtspsrc_finalize (GObject * object)
gst_rtsp_ext_list_free (rtspsrc->extensions); gst_rtsp_ext_list_free (rtspsrc->extensions);
g_free (rtspsrc->location); g_free (rtspsrc->location);
g_free (rtspsrc->req_location); g_free (rtspsrc->req_location);
g_free (rtspsrc->content_base);
gst_rtsp_url_free (rtspsrc->url); gst_rtsp_url_free (rtspsrc->url);
/* free locks */ /* free locks */
@ -823,6 +821,13 @@ gst_rtspsrc_cleanup (GstRTSPSrc * src)
if (src->props) if (src->props)
gst_structure_free (src->props); gst_structure_free (src->props);
src->props = NULL; src->props = NULL;
g_free (src->content_base);
src->content_base = NULL;
if (src->range)
gst_rtsp_range_free (src->range);
src->range = NULL;
} }
#define PARSE_INT(p, del, res) \ #define PARSE_INT(p, del, res) \
@ -4173,13 +4178,25 @@ static void
gst_rtspsrc_parse_range (GstRTSPSrc * src, const gchar * range, gst_rtspsrc_parse_range (GstRTSPSrc * src, const gchar * range,
GstSegment * segment) GstSegment * segment)
{ {
gint64 seconds;
GstRTSPTimeRange *therange; GstRTSPTimeRange *therange;
if (gst_rtsp_range_parse (range, &therange) == GST_RTSP_OK) { if (src->range)
gint64 seconds; gst_rtsp_range_free (src->range);
GST_DEBUG_OBJECT (src, "range: '%s', min %f - max %f ", if (gst_rtsp_range_parse (range, &therange) == GST_RTSP_OK) {
GST_STR_NULL (range), therange->min.seconds, therange->max.seconds); GST_DEBUG_OBJECT (src, "parsed range %s", range);
src->range = therange;
} else {
GST_DEBUG_OBJECT (src, "failed to parse range %s", range);
src->range = NULL;
gst_segment_init (segment, GST_FORMAT_TIME);
return;
}
GST_DEBUG_OBJECT (src, "range: type %d, min %f - type %d, max %f ",
therange->min.type, therange->min.seconds, therange->max.type,
therange->max.seconds);
if (therange->min.type == GST_RTSP_TIME_NOW) if (therange->min.type == GST_RTSP_TIME_NOW)
seconds = 0; seconds = 0;
@ -4210,11 +4227,6 @@ gst_rtspsrc_parse_range (GstRTSPSrc * src, const gchar * range,
* there that we want to keep. */ * there that we want to keep. */
if (seconds != -1) if (seconds != -1)
gst_segment_set_duration (segment, GST_FORMAT_TIME, seconds); gst_segment_set_duration (segment, GST_FORMAT_TIME, seconds);
gst_rtsp_range_free (therange);
} else {
GST_WARNING_OBJECT (src, "could not parse range: '%s'", range);
}
} }
static gboolean static gboolean
@ -4352,9 +4364,11 @@ restart:
const gchar *range; const gchar *range;
range = gst_sdp_message_get_attribute_val (&sdp, "range"); range = gst_sdp_message_get_attribute_val (&sdp, "range");
if (range) if (range) {
/* keep track of the range and configure it in the segment */
gst_rtspsrc_parse_range (src, range, &src->segment); gst_rtspsrc_parse_range (src, range, &src->segment);
} }
}
/* create streams */ /* create streams */
n_streams = gst_sdp_message_medias_len (&sdp); n_streams = gst_sdp_message_medias_len (&sdp);
@ -4665,6 +4679,23 @@ gst_rtspsrc_get_float (const char *str, gfloat * val)
RESTORE_LOCALE return result; RESTORE_LOCALE return result;
} }
static gchar *
gen_range_header (GstRTSPSrc * src, GstSegment * segment)
{
gchar *res;
if (src->range && src->range->min.type == GST_RTSP_TIME_NOW) {
res = g_strdup_printf ("npt=now-");
} else {
if (segment->last_stop == 0)
res = g_strdup_printf ("npt=0-");
else
res = gst_rtspsrc_dup_printf ("npt=%f-",
((gdouble) segment->last_stop) / GST_SECOND);
}
return res;
}
static gboolean static gboolean
gst_rtspsrc_play (GstRTSPSrc * src, GstSegment * segment) gst_rtspsrc_play (GstRTSPSrc * src, GstSegment * segment)
{ {
@ -4691,12 +4722,7 @@ gst_rtspsrc_play (GstRTSPSrc * src, GstSegment * segment)
goto create_request_failed; goto create_request_failed;
if (src->need_range) { if (src->need_range) {
if (segment->last_stop == 0) hval = gen_range_header (src, segment);
hval = g_strdup_printf ("npt=0-");
else
hval =
gst_rtspsrc_dup_printf ("npt=%f-",
((gdouble) segment->last_stop) / GST_SECOND);
gst_rtsp_message_add_header (&request, GST_RTSP_HDR_RANGE, hval); gst_rtsp_message_add_header (&request, GST_RTSP_HDR_RANGE, hval);
g_free (hval); g_free (hval);

View file

@ -51,6 +51,7 @@ G_BEGIN_DECLS
#include <gst/rtsp/gstrtspconnection.h> #include <gst/rtsp/gstrtspconnection.h>
#include <gst/rtsp/gstrtspmessage.h> #include <gst/rtsp/gstrtspmessage.h>
#include <gst/rtsp/gstrtspurl.h> #include <gst/rtsp/gstrtspurl.h>
#include <gst/rtsp/gstrtsprange.h>
#include "gstrtspext.h" #include "gstrtspext.h"
@ -195,6 +196,7 @@ struct _GstRTSPSrc {
gboolean tried_url_auth; gboolean tried_url_auth;
gchar *addr; gchar *addr;
gboolean need_redirect; gboolean need_redirect;
GstRTSPTimeRange *range;
/* supported methods */ /* supported methods */
gint methods; gint methods;