diff --git a/gst/gstdatetime.c b/gst/gstdatetime.c index 7f6ba4338b..ec982937fc 100644 --- a/gst/gstdatetime.c +++ b/gst/gstdatetime.c @@ -42,6 +42,34 @@ * Since: 0.10.31 */ +#define GST_DATE_TIME_SEC_PER_DAY (G_GINT64_CONSTANT (86400)) +#define GST_DATE_TIME_USEC_PER_DAY (G_GINT64_CONSTANT (86400000000)) +#define GST_DATE_TIME_USEC_PER_HOUR (G_GINT64_CONSTANT (3600000000)) +#define GST_DATE_TIME_USEC_PER_MINUTE (G_GINT64_CONSTANT (60000000)) +#define GST_DATE_TIME_USEC_PER_SECOND (G_GINT64_CONSTANT (1000000)) +#define GST_DATE_TIME_USEC_PER_MILLISECOND (G_GINT64_CONSTANT (1000)) + +struct _GstDateTime +{ + GDateTime *datetime; + + volatile gint ref_count; +}; + +static GstDateTime * +gst_date_time_new_from_gdatetime (GDateTime * dt) +{ + GstDateTime *gst_dt; + + if (!dt) + return NULL; + + gst_dt = g_slice_new (GstDateTime); + gst_dt->datetime = dt; + gst_dt->ref_count = 1; + return gst_dt; +} + /** * gst_date_time_get_year: * @datetime: a #GstDateTime @@ -51,6 +79,11 @@ * Return value: The year of this #GstDateTime * Since: 0.10.31 */ +gint +gst_date_time_get_year (const GstDateTime * datetime) +{ + return g_date_time_get_year (datetime->datetime); +} /** * gst_date_time_get_month: @@ -61,6 +94,11 @@ * Return value: The month of this #GstDateTime * Since: 0.10.31 */ +gint +gst_date_time_get_month (const GstDateTime * datetime) +{ + return g_date_time_get_month (datetime->datetime); +} /** * gst_date_time_get_day: @@ -71,6 +109,11 @@ * Return value: The day of this #GstDateTime * Since: 0.10.31 */ +gint +gst_date_time_get_day (const GstDateTime * datetime) +{ + return g_date_time_get_day_of_month (datetime->datetime); +} /** * gst_date_time_get_hour: @@ -83,18 +126,11 @@ * * Since: 0.10.31 */ - -/** - * gst_date_time_get_microsecond: - * @datetime: a #GstDateTime - * - * Retrieves the fractional part of the seconds in microseconds represented by - * @datetime in the gregorian calendar. - * - * Return value: the microsecond of the second - * - * Since: 0.10.31 - */ +gint +gst_date_time_get_hour (const GstDateTime * datetime) +{ + return g_date_time_get_hour (datetime->datetime); +} /** * gst_date_time_get_minute: @@ -107,6 +143,11 @@ * * Since: 0.10.31 */ +gint +gst_date_time_get_minute (const GstDateTime * datetime) +{ + return g_date_time_get_minute (datetime->datetime); +} /** * gst_date_time_get_second: @@ -119,18 +160,28 @@ * * Since: 0.10.31 */ +gint +gst_date_time_get_second (const GstDateTime * datetime) +{ + return g_date_time_get_second (datetime->datetime); +} /** - * gst_date_time_get_second: + * gst_date_time_get_microsecond: * @datetime: a #GstDateTime * - * Retrieves the second of the minute represented by @datetime in the gregorian - * calendar. + * Retrieves the fractional part of the seconds in microseconds represented by + * @datetime in the gregorian calendar. * - * Return value: the second represented by @datetime + * Return value: the microsecond of the second * * Since: 0.10.31 */ +gint +gst_date_time_get_microsecond (const GstDateTime * datetime) +{ + return g_date_time_get_microsecond (datetime->datetime); +} /** * gst_date_time_get_time_zone_offset: @@ -144,6 +195,12 @@ * Return value: the offset from UTC in hours * Since: 0.10.31 */ +gfloat +gst_date_time_get_time_zone_offset (const GstDateTime * datetime) +{ + return (g_date_time_get_utc_offset (datetime->datetime) / + G_USEC_PER_SEC) / 3600.0; +} /** * gst_date_time_new_from_unix_epoch_local_time: @@ -158,6 +215,12 @@ * * Since: 0.10.31 */ +GstDateTime * +gst_date_time_new_from_unix_epoch_local_time (gint64 secs) +{ + return + gst_date_time_new_from_gdatetime (g_date_time_new_from_unix_local (secs)); +} /** * gst_date_time_new_from_unix_epoch_utc: @@ -172,6 +235,12 @@ * * Since: 0.10.31 */ +GstDateTime * +gst_date_time_new_from_unix_epoch_utc (gint64 secs) +{ + return + gst_date_time_new_from_gdatetime (g_date_time_new_from_unix_utc (secs)); +} /** * gst_date_time_new_local_time: @@ -194,6 +263,58 @@ * * Since: 0.10.31 */ +GstDateTime * +gst_date_time_new_local_time (gint year, gint month, gint day, gint hour, + gint minute, gdouble seconds) +{ + return gst_date_time_new_from_gdatetime (g_date_time_new_local (year, month, + day, hour, minute, seconds)); +} + +/** + * gst_date_time_new_now_local_time: + * + * Creates a new #GstDateTime representing the current date and time. + * + * Free-function: gst_date_time_unref + * + * Return value: (transfer full): the newly created #GstDateTime which should + * be freed with gst_date_time_unref(). + * + * Since: 0.10.31 + */ +GstDateTime * +gst_date_time_new_now_local_time (void) +{ + return gst_date_time_new_from_gdatetime (g_date_time_new_now_local ()); +} + +/** + * gst_date_time_new_now_utc: + * + * Creates a new #GstDateTime that represents the current instant at Universal + * coordinated time. + * + * Free-function: gst_date_time_unref + * + * Return value: (transfer full): the newly created #GstDateTime which should + * be freed with gst_date_time_unref(). + * + * Since: 0.10.31 + */ +GstDateTime * +gst_date_time_new_now_utc (void) +{ + return gst_date_time_new_from_gdatetime (g_date_time_new_now_utc ()); +} + +gint +priv_gst_date_time_compare (gconstpointer dt1, gconstpointer dt2) +{ + const GstDateTime *datetime1 = dt1; + const GstDateTime *datetime2 = dt2; + return g_date_time_compare (datetime1->datetime, datetime2->datetime); +} /** * gst_date_time_new: @@ -221,534 +342,6 @@ * * Since: 0.10.31 */ - -/** - * gst_date_time_new_now_local_time: - * - * Creates a new #GstDateTime representing the current date and time. - * - * Free-function: gst_date_time_unref - * - * Return value: (transfer full): the newly created #GstDateTime which should - * be freed with gst_date_time_unref(). - * - * Since: 0.10.31 - */ - -/** - * gst_date_time_new_now_utc: - * - * Creates a new #GstDateTime that represents the current instant at Universal - * coordinated time. - * - * Free-function: gst_date_time_unref - * - * Return value: (transfer full): the newly created #GstDateTime which should - * be freed with gst_date_time_unref(). - * - * Since: 0.10.31 - */ - - -#define GST_DATE_TIME_SEC_PER_DAY (G_GINT64_CONSTANT (86400)) -#define GST_DATE_TIME_USEC_PER_DAY (G_GINT64_CONSTANT (86400000000)) -#define GST_DATE_TIME_USEC_PER_HOUR (G_GINT64_CONSTANT (3600000000)) -#define GST_DATE_TIME_USEC_PER_MINUTE (G_GINT64_CONSTANT (60000000)) -#define GST_DATE_TIME_USEC_PER_SECOND (G_GINT64_CONSTANT (1000000)) -#define GST_DATE_TIME_USEC_PER_MILLISECOND (G_GINT64_CONSTANT (1000)) - -/* FIXME: this bug was resolved NOTGNOME */ -/* Jan 5th 2011 (Edward) : GLib's GDateTime is broken in regards to gmt offset - * on macosx. Re-enable it once the following bug is fixed: - * https://bugzilla.gnome.org/show_bug.cgi?id=638666 */ -#ifdef HAVE_OSX -#undef GLIB_HAS_GDATETIME -#else -#define GLIB_HAS_GDATETIME -#endif - - -#ifndef GLIB_HAS_GDATETIME - -#define MAX_SUPPORTED_YEAR 9999 -#define GREGORIAN_LEAP(y) (((y%4)==0)&&(!(((y%100)==0)&&((y%400)!=0)))) - -static const guint16 days_in_months[2][13] = { - {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, - {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} -}; - -struct _GstDateTime -{ - /* - * As we don't have a datetime math API, we can have fields split here. - * (There is still some math done internally, but nothing really relevant). - * - * If we ever add one, we should go for a days since some epoch counter. - * (Proleptic Gregorian with 0001-01-01 as day 1) - */ - gint16 year; - gint8 month; - gint8 day; - guint64 usec; /* Microsecond timekeeping within Day */ - - gint tzoffset; - - volatile gint ref_count; -}; - -/* - * Returns the utc offset in seconds for this time structure - */ -static gint -gmt_offset (struct tm *tm, time_t t) -{ -#if defined (HAVE_TM_GMTOFF) - return tm->tm_gmtoff; -#else - struct tm g; - time_t t2; -#ifdef HAVE_GMTIME_R - gmtime_r (&t, &g); -#else - g = *gmtime (&t); -#endif - t2 = mktime (&g); - return (int) difftime (t, t2); -#endif -} - -static void -gst_date_time_set_local_timezone (GstDateTime * dt) -{ - struct tm tt; - time_t t; - - g_return_if_fail (dt != NULL); - - memset (&tt, 0, sizeof (tt)); - - tt.tm_mday = gst_date_time_get_day (dt); - tt.tm_mon = gst_date_time_get_month (dt) - 1; - tt.tm_year = gst_date_time_get_year (dt) - 1900; - tt.tm_hour = gst_date_time_get_hour (dt); - tt.tm_min = gst_date_time_get_minute (dt); - tt.tm_sec = gst_date_time_get_second (dt); - - t = mktime (&tt); - - dt->tzoffset = gmt_offset (&tt, t) / 60; -} - -static GstDateTime * -gst_date_time_alloc (void) -{ - GstDateTime *datetime; - - datetime = g_slice_new0 (GstDateTime); - datetime->ref_count = 1; - - return datetime; -} - -static void -gst_date_time_free (GstDateTime * datetime) -{ - g_slice_free (GstDateTime, datetime); -} - -static GstDateTime * -gst_date_time_new_from_date (gint year, gint month, gint day) -{ - GstDateTime *dt; - - g_return_val_if_fail (year > 0 && year <= 9999, NULL); - g_return_val_if_fail ((month > 0 && month <= 12), NULL); - g_return_val_if_fail ((day > 0 && day <= 31), NULL); - - dt = gst_date_time_alloc (); - - dt->year = year; - dt->month = month; - dt->day = day; - gst_date_time_set_local_timezone (dt); - - return dt; -} - -gint -gst_date_time_get_year (const GstDateTime * datetime) -{ - g_return_val_if_fail (datetime != NULL, 0); - - return datetime->year; -} - -gint -gst_date_time_get_month (const GstDateTime * datetime) -{ - g_return_val_if_fail (datetime != NULL, 0); - - return datetime->month; -} - -gint -gst_date_time_get_day (const GstDateTime * datetime) -{ - g_return_val_if_fail (datetime != NULL, 0); - - return datetime->day; -} - -gint -gst_date_time_get_hour (const GstDateTime * datetime) -{ - g_return_val_if_fail (datetime != NULL, 0); - return (datetime->usec / GST_DATE_TIME_USEC_PER_HOUR); -} - -gint -gst_date_time_get_microsecond (const GstDateTime * datetime) -{ - g_return_val_if_fail (datetime != NULL, 0); - return (datetime->usec % GST_DATE_TIME_USEC_PER_SECOND); -} - -gint -gst_date_time_get_minute (const GstDateTime * datetime) -{ - g_return_val_if_fail (datetime != NULL, 0); - return (datetime->usec % GST_DATE_TIME_USEC_PER_HOUR) / - GST_DATE_TIME_USEC_PER_MINUTE; -} - -gint -gst_date_time_get_second (const GstDateTime * datetime) -{ - g_return_val_if_fail (datetime != NULL, 0); - return (datetime->usec % GST_DATE_TIME_USEC_PER_MINUTE) / - GST_DATE_TIME_USEC_PER_SECOND; -} - -gfloat -gst_date_time_get_time_zone_offset (const GstDateTime * datetime) -{ - g_return_val_if_fail (datetime != NULL, 0); - - return datetime->tzoffset / 60.0f; -} - -GstDateTime * -gst_date_time_new_from_unix_epoch_local_time (gint64 secs) -{ - GstDateTime *dt; - struct tm tm; - time_t tt; - - memset (&tm, 0, sizeof (tm)); - tt = (time_t) secs; - -#ifdef HAVE_LOCALTIME_R - localtime_r (&tt, &tm); -#else - memcpy (&tm, localtime (&tt), sizeof (struct tm)); -#endif - - dt = gst_date_time_new (0, tm.tm_year + 1900, - tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); - gst_date_time_set_local_timezone (dt); - return dt; -} - -GstDateTime * -gst_date_time_new_from_unix_epoch_utc (gint64 secs) -{ - GstDateTime *dt; - struct tm tm; - time_t tt; - - memset (&tm, 0, sizeof (tm)); - tt = (time_t) secs; - -#ifdef HAVE_GMTIME_R - gmtime_r (&tt, &tm); -#else - memcpy (&tm, gmtime (&tt), sizeof (struct tm)); -#endif - - dt = gst_date_time_new (0, tm.tm_year + 1900, - tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); - return dt; -} - -GstDateTime * -gst_date_time_new_local_time (gint year, gint month, gint day, gint hour, - gint minute, gdouble seconds) -{ - GstDateTime *dt; - - dt = gst_date_time_new (0, year, month, day, hour, minute, seconds); - - gst_date_time_set_local_timezone (dt); - - return dt; -} - -GstDateTime * -gst_date_time_new (gfloat tzoffset, gint year, gint month, gint day, gint hour, - gint minute, gdouble seconds) -{ - GstDateTime *dt; - - g_return_val_if_fail (hour >= 0 && hour < 24, NULL); - g_return_val_if_fail (minute >= 0 && minute < 60, NULL); - g_return_val_if_fail (seconds >= 0 && seconds < 60, NULL); - g_return_val_if_fail (tzoffset >= -12.0 && tzoffset <= 12.0, NULL); - - if (!(dt = gst_date_time_new_from_date (year, month, day))) - return NULL; - - dt->usec = (hour * GST_DATE_TIME_USEC_PER_HOUR) - + (minute * GST_DATE_TIME_USEC_PER_MINUTE) - + (guint64) (floor (seconds * GST_DATE_TIME_USEC_PER_SECOND + 0.5)); - - /* we store in minutes */ - dt->tzoffset = (gint) (tzoffset * 60.0); - - return dt; -} - -GstDateTime * -gst_date_time_new_now_local_time (void) -{ - GstDateTime *datetime; - GTimeVal tv; - g_get_current_time (&tv); - - datetime = gst_date_time_new_from_unix_epoch_local_time (tv.tv_sec); - datetime->usec += tv.tv_usec; - gst_date_time_set_local_timezone (datetime); - return datetime; -} - -static GstDateTime * -gst_date_time_copy (const GstDateTime * dt) -{ - GstDateTime *copy = gst_date_time_alloc (); - - memcpy (copy, dt, sizeof (GstDateTime)); - copy->ref_count = 1; - - return copy; -} - -static GstDateTime * -gst_date_time_to_utc (const GstDateTime * dt) -{ - GstDateTime *utc; - gint64 usec; - gint days; - gint leap; - - g_return_val_if_fail (dt != NULL, NULL); - - utc = gst_date_time_copy (dt); - - usec = dt->usec - dt->tzoffset * GST_DATE_TIME_USEC_PER_MINUTE; - days = usec / GST_DATE_TIME_USEC_PER_DAY; - if (usec < 0) - days--; - utc->day += days; - - leap = GREGORIAN_LEAP (utc->year) ? 1 : 0; - - /* check if we should update month/year */ - if (utc->day < 1) { - if (utc->month == 1) { - utc->year--; - utc->month = 12; - } else { - utc->month--; - } - if (GREGORIAN_LEAP (utc->year)) - utc->day = days_in_months[1][utc->month]; - else - utc->day = days_in_months[0][utc->month]; - } else if (utc->day > days_in_months[leap][utc->month]) { - if (utc->month == 12) { - utc->year++; - utc->month = 1; - } else { - utc->month++; - } - utc->day = 1; - } - - if (usec < 0) - utc->usec = - GST_DATE_TIME_USEC_PER_DAY + (usec % GST_DATE_TIME_USEC_PER_DAY); - else - utc->usec = usec % GST_DATE_TIME_USEC_PER_DAY; - - return utc; -} - -GstDateTime * -gst_date_time_new_now_utc (void) -{ - GstDateTime *now, *utc; - - now = gst_date_time_new_now_local_time (); - utc = gst_date_time_to_utc (now); - gst_date_time_unref (now); - return utc; -} - -gint -priv_gst_date_time_compare (gconstpointer dt1, gconstpointer dt2) -{ - GstDateTime *a, *b; - gint res = 0; - - a = gst_date_time_to_utc (dt1); - b = gst_date_time_to_utc (dt2); - -#define GST_DATE_TIME_COMPARE_VALUE(a,b,v) \ - if ((a)->v > (b)->v) { \ - res = 1; \ - goto done; \ - } else if ((a)->v < (b)->v) { \ - res = -1; \ - goto done; \ - } - - GST_DATE_TIME_COMPARE_VALUE (a, b, year); - GST_DATE_TIME_COMPARE_VALUE (a, b, month); - GST_DATE_TIME_COMPARE_VALUE (a, b, day); - GST_DATE_TIME_COMPARE_VALUE (a, b, usec); - -#undef GST_DATE_TIME_COMPARE_VALUE - -done: - gst_date_time_unref (a); - gst_date_time_unref (b); - return res; -} - -#else - -struct _GstDateTime -{ - GDateTime *datetime; - - volatile gint ref_count; -}; - -static GstDateTime * -gst_date_time_new_from_gdatetime (GDateTime * dt) -{ - GstDateTime *gst_dt; - - if (!dt) - return NULL; - - gst_dt = g_slice_new (GstDateTime); - gst_dt->datetime = dt; - gst_dt->ref_count = 1; - return gst_dt; -} - -gint -gst_date_time_get_year (const GstDateTime * datetime) -{ - return g_date_time_get_year (datetime->datetime); -} - -gint -gst_date_time_get_month (const GstDateTime * datetime) -{ - return g_date_time_get_month (datetime->datetime); -} - -gint -gst_date_time_get_day (const GstDateTime * datetime) -{ - return g_date_time_get_day_of_month (datetime->datetime); -} - -gint -gst_date_time_get_hour (const GstDateTime * datetime) -{ - return g_date_time_get_hour (datetime->datetime); -} - -gint -gst_date_time_get_minute (const GstDateTime * datetime) -{ - return g_date_time_get_minute (datetime->datetime); -} - -gint -gst_date_time_get_second (const GstDateTime * datetime) -{ - return g_date_time_get_second (datetime->datetime); -} - -gint -gst_date_time_get_microsecond (const GstDateTime * datetime) -{ - return g_date_time_get_microsecond (datetime->datetime); -} - -gfloat -gst_date_time_get_time_zone_offset (const GstDateTime * datetime) -{ - return (g_date_time_get_utc_offset (datetime->datetime) / - G_USEC_PER_SEC) / 3600.0; -} - -GstDateTime * -gst_date_time_new_from_unix_epoch_local_time (gint64 secs) -{ - return - gst_date_time_new_from_gdatetime (g_date_time_new_from_unix_local (secs)); -} - -GstDateTime * -gst_date_time_new_from_unix_epoch_utc (gint64 secs) -{ - return - gst_date_time_new_from_gdatetime (g_date_time_new_from_unix_utc (secs)); -} - -GstDateTime * -gst_date_time_new_local_time (gint year, gint month, gint day, gint hour, - gint minute, gdouble seconds) -{ - return gst_date_time_new_from_gdatetime (g_date_time_new_local (year, month, - day, hour, minute, seconds)); -} - -GstDateTime * -gst_date_time_new_now_local_time (void) -{ - return gst_date_time_new_from_gdatetime (g_date_time_new_now_local ()); -} - -GstDateTime * -gst_date_time_new_now_utc (void) -{ - return gst_date_time_new_from_gdatetime (g_date_time_new_now_utc ()); -} - -gint -priv_gst_date_time_compare (gconstpointer dt1, gconstpointer dt2) -{ - const GstDateTime *datetime1 = dt1; - const GstDateTime *datetime2 = dt2; - return g_date_time_compare (datetime1->datetime, datetime2->datetime); -} - GstDateTime * gst_date_time_new (gfloat tzoffset, gint year, gint month, gint day, gint hour, gint minute, gdouble seconds) @@ -778,8 +371,6 @@ gst_date_time_free (GstDateTime * datetime) g_slice_free (GstDateTime, datetime); } -#endif - /** * gst_date_time_ref: * @datetime: a #GstDateTime