From 799d034b9733969dd569f627301b68a274d54907 Mon Sep 17 00:00:00 2001 From: Georgi Chorbadzhiyski Date: Mon, 10 Oct 2011 15:18:36 +0300 Subject: [PATCH] dvb/si/datetime: Add more helper functions. --- dvb/si/datetime.h | 74 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/dvb/si/datetime.h b/dvb/si/datetime.h index 163c9ed..e276e9e 100644 --- a/dvb/si/datetime.h +++ b/dvb/si/datetime.h @@ -4,6 +4,7 @@ * Copyright (C) 2009-2010 VideoLAN * * Authors: Christophe Massiot + * Georgi Chorbadzhiyski * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -27,6 +28,9 @@ #include +#include /* gmtime_r, time_t */ +#include /* sprintf */ + /* * Normative references: * - ETSI EN 300 468 V1.11.1 (2010-04) (SI in DVB systems) @@ -63,6 +67,76 @@ static inline void dvb_mjd_get(uint16_t mjd, int *y, int *m, int *d) *m = mp - 1 - k * 12; } +#define bcd2dec(__bcd) (int)((((__bcd) >> 4) * 10) + (__bcd) % 16) +static inline void dvb_time_decode_bcd(uint32_t bcd, int *seconds, int *hour, int *min, int *sec) { + *hour = bcd2dec( (bcd >> 16) & 0xff ); + *min = bcd2dec( (bcd >> 8) & 0xff ); + *sec = bcd2dec( bcd & 0xff ); + if (seconds) + *seconds = *hour * 3600 + *min * 60 + *sec; +} +#undef bcd2dec + +static inline time_t dvb_time_decode_UTC(uint64_t UTC_time) { + struct tm tm; + uint16_t mjd = (UTC_time >> 24) & 0xffff; + uint32_t bcd = UTC_time & 0xffffff; + + dvb_mjd_get(mjd, &tm.tm_year, &tm.tm_mon, &tm.tm_mday); + /* DVB months are 1..12, struct tm needs 0..11 */ + tm.tm_mon -= 1; + + dvb_time_decode_bcd(bcd, NULL, &tm.tm_hour, &tm.tm_min, &tm.tm_sec); + + return timegm(&tm); +} + +#define dec2bcd(__dec) (int)((((__dec)/10) << 4) + (__dec) % 10) +static inline uint64_t dvb_time_encode_UTC(time_t ts) { + struct tm tm; + uint16_t mjd = 0; + uint32_t bcd = 0; + + gmtime_r(&ts, &tm); + + mjd = dvb_mjd_set(tm.tm_year, tm.tm_mon + 1, tm.tm_mday); + + bcd = dec2bcd(tm.tm_hour) << 16; + bcd |= dec2bcd(tm.tm_min ) << 8; + bcd |= dec2bcd(tm.tm_sec ); + + return (uint64_t)((uint64_t)mjd << 24) | bcd; +} + +static inline uint32_t dvb_time_encode_duration(unsigned int duration_sec) +{ + unsigned int t_sec, t_min, t_hour, ret; + t_sec = duration_sec % 60; + t_min = (duration_sec - t_sec) / 60; + t_hour = (t_min - t_min % 60) / 60; + t_min = t_min - t_hour * 60; + + ret = dec2bcd(t_hour) << 16; + ret |= dec2bcd(t_min ) << 8; + ret |= dec2bcd(t_sec ); + + return ret; +} +#undef dec2bcd + +static time_t dvb_time_format_UTC(uint64_t UTC_time, struct tm *tm, char *output) { + struct tm tm_local; + if (tm == NULL) + tm = &tm_local; + time_t ts = dvb_time_decode_UTC(UTC_time); + tm = gmtime_r(&ts, tm); + if (output) + sprintf(output, "%04d-%02d-%02d %02d:%02d:%02d UTC", + tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); + return ts; +} + #ifdef __cplusplus } #endif