diff --git a/gst-libs/gst/rtsp/gstrtsprange.c b/gst-libs/gst/rtsp/gstrtsprange.c index 76701fa5df..3c914c9d25 100644 --- a/gst-libs/gst/rtsp/gstrtsprange.c +++ b/gst-libs/gst/rtsp/gstrtsprange.c @@ -132,16 +132,62 @@ done: return res; } + static GstRTSPResult parse_clock_range (const gchar * str, GstRTSPTimeRange * range) { return GST_RTSP_ENOTIMPL; } +/* smpte-time = 1*2DIGIT ":" 1*2DIGIT ":" 1*2DIGIT [ ":" 1*2DIGIT ] + * [ "." 1*2DIGIT ] + * hours:minutes:seconds:frames.subframes +*/ +static GstRTSPResult +parse_smpte_time (const gchar * str, GstRTSPTime * time, const gchar * limit) +{ + gint hours, mins, secs; + + if (str[0] == '\0') { + time->type = GST_RTSP_TIME_END; + return GST_RTSP_OK; + } else { + if (sscanf (str, "%02d:%2d:%02d", &hours, &mins, &secs) != 3) + return GST_RTSP_EINVAL; + + time->type = GST_RTSP_TIME_FRAMES; + time->seconds = ((hours * 60) + mins) * 60 + secs; + str = strchr (str, ':'); + str = strchr (str + 1, ':'); + str = strchr (str + 1, ':'); + if (str && (limit == NULL || str < limit)) + time->frames = gst_strtod (str + 1); + } + return GST_RTSP_OK; +} + +/* smpte-range = smpte-type "=" smpte-time "-" [ smpte-time ] + */ static GstRTSPResult parse_smpte_range (const gchar * str, GstRTSPTimeRange * range) { - return GST_RTSP_ENOTIMPL; + GstRTSPResult res; + gchar *p; + + range->unit = GST_RTSP_RANGE_SMPTE; + + /* find '-' separator, can't have a single - */ + p = strstr (str, "-"); + if (p == NULL || p == str) + return GST_RTSP_EINVAL; + + if ((res = parse_smpte_time (str, &range->min, p)) != GST_RTSP_OK) + goto done; + + res = parse_smpte_time (p + 1, &range->max, NULL); + +done: + return res; } /** diff --git a/gst-libs/gst/rtsp/gstrtsprange.h b/gst-libs/gst/rtsp/gstrtsprange.h index 5e6034c089..9d86686248 100644 --- a/gst-libs/gst/rtsp/gstrtsprange.h +++ b/gst-libs/gst/rtsp/gstrtsprange.h @@ -76,25 +76,30 @@ typedef struct _GstRTSPTime GstRTSPTime; * @GST_RTSP_TIME_SECONDS: seconds * @GST_RTSP_TIME_NOW: now * @GST_RTSP_TIME_END: end + * @GST_RTSP_TIME_FRAMES: frames and subframes * * Possible time types. */ typedef enum { GST_RTSP_TIME_SECONDS, GST_RTSP_TIME_NOW, - GST_RTSP_TIME_END + GST_RTSP_TIME_END, + GST_RTSP_TIME_FRAMES } GstRTSPTimeType; /** * GstRTSPTime: * @type: the time of the time - * @seconds: seconds when @type is GST_RTSP_TIME_SECONDS + * @seconds: seconds when @type is GST_RTSP_TIME_SECONDS and + * GST_RTSP_TIME_FRAMES + * @frames: frames and subframes when @type is GST_RTSP_TIME_FRAMES * * A time indication. */ struct _GstRTSPTime { GstRTSPTimeType type; gdouble seconds; + gdouble frames; }; /** diff --git a/tests/check/libs/rtsp.c b/tests/check/libs/rtsp.c index faed017e98..f9d422eb5d 100644 --- a/tests/check/libs/rtsp.c +++ b/tests/check/libs/rtsp.c @@ -199,10 +199,60 @@ GST_START_TEST (test_rtsp_range_npt) fail_unless (range->max.type == GST_RTSP_TIME_SECONDS); fail_unless (range->max.seconds == 15.001); gst_rtsp_range_free (range); + + fail_unless (gst_rtsp_range_parse ("npt=20:34.23-", + &range) == GST_RTSP_EINVAL); + fail_unless (gst_rtsp_range_parse ("npt=10:20;34.23-", + &range) == GST_RTSP_EINVAL); + fail_unless (gst_rtsp_range_parse ("npt=0:4.23-", &range) == GST_RTSP_EINVAL); + + fail_unless (gst_rtsp_range_parse ("npt=20:12:34.23-21:45:00.01", + &range) == GST_RTSP_OK); + fail_unless (range->unit == GST_RTSP_RANGE_NPT); + fail_unless (range->min.type == GST_RTSP_TIME_SECONDS); + fail_unless (range->min.seconds == 72754.23); + fail_unless (range->max.type == GST_RTSP_TIME_SECONDS); + fail_unless (range->max.seconds == 78300.01); + gst_rtsp_range_free (range); } GST_END_TEST; +GST_START_TEST (test_rtsp_range_smpte) +{ + GstRTSPTimeRange *range; + + fail_unless (gst_rtsp_range_parse ("smpte=", &range) == GST_RTSP_EINVAL); + fail_unless (gst_rtsp_range_parse ("smpte=0", &range) == GST_RTSP_EINVAL); + fail_unless (gst_rtsp_range_parse ("smpte=-", &range) == GST_RTSP_EINVAL); + fail_unless (gst_rtsp_range_parse ("smpte=-12:09:34", + &range) == GST_RTSP_EINVAL); + fail_unless (gst_rtsp_range_parse ("smpte=12:09:34", + &range) == GST_RTSP_EINVAL); + + fail_unless (gst_rtsp_range_parse ("smpte=00:00:00-", &range) == GST_RTSP_OK); + fail_unless (range->unit == GST_RTSP_RANGE_SMPTE); + fail_unless (range->min.type == GST_RTSP_TIME_FRAMES); + fail_unless (range->min.seconds == 0.0); + fail_unless (range->min.frames == 0.0); + fail_unless (range->max.type == GST_RTSP_TIME_END); + gst_rtsp_range_free (range); + + fail_unless (gst_rtsp_range_parse ("smpte=10:34:23-20:12:09:20.89", + &range) == GST_RTSP_OK); + fail_unless (range->unit == GST_RTSP_RANGE_SMPTE); + fail_unless (range->min.type == GST_RTSP_TIME_FRAMES); + fail_unless (range->min.seconds == 38063.0); + fail_unless (range->min.frames == 0.0); + fail_unless (range->max.type == GST_RTSP_TIME_FRAMES); + fail_unless (range->max.seconds == 72729.0); + fail_unless (range->max.frames == 20.89); + gst_rtsp_range_free (range); +} + +GST_END_TEST; + + static Suite * rtsp_suite (void) { @@ -215,6 +265,7 @@ rtsp_suite (void) tcase_add_test (tc_chain, test_rtsp_url_components_2); tcase_add_test (tc_chain, test_rtsp_url_components_3); tcase_add_test (tc_chain, test_rtsp_range_npt); + tcase_add_test (tc_chain, test_rtsp_range_smpte); return s; }