libtsfuncs is a library for mpeg PSI parsing and generation. https://georgi.unixsol.org/programs/libtsfuncs/

time.c 2.5KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*
  2. * DVB time functions
  3. * Copyright (C) 2010-2011 Unix Solutions Ltd.
  4. *
  5. * Released under MIT license.
  6. * See LICENSE-MIT.txt for license terms.
  7. */
  8. #include <stdio.h>
  9. #include <unistd.h>
  10. #include <netdb.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <time.h>
  14. #include "tsfuncs.h"
  15. uint32_t ts_time_encode_bcd(int duration_sec) {
  16. int t_sec, t_min, t_hour, ret;
  17. t_sec = duration_sec % 60;
  18. t_min = (duration_sec - t_sec) / 60;
  19. t_hour = (t_min - t_min % 60) / 60;
  20. t_min = t_min - t_hour * 60;
  21. ret = dec2bcd(t_hour) << 16;
  22. ret |= dec2bcd(t_min ) << 8;
  23. ret |= dec2bcd(t_sec );
  24. return ret;
  25. }
  26. void ts_time_decode_bcd(int duration_bcd, int *duration_sec, int *hour, int *min, int *sec) {
  27. *hour = bcd2dec( (duration_bcd &~ 0xff00ffff) >> 16 ); // 11111111 xxxxxxxx xxxxxxxx
  28. *min = bcd2dec( (duration_bcd &~ 0xffff00ff) >> 8 ); // xxxxxxxx 11111111 xxxxxxxx
  29. *sec = bcd2dec( (duration_bcd &~ 0xffffff00) ); // xxxxxxxx xxxxxxxx 11111111
  30. if (duration_sec)
  31. *duration_sec = *hour * 3600 + *min * 60 + *sec;
  32. }
  33. void ts_time_encode_mjd(uint16_t *mjd, uint32_t *bcd, time_t *ts, struct tm *tm) {
  34. struct tm *ltm = tm;
  35. if (!ts && !tm)
  36. return;
  37. if (ts) { // Decompose ts into struct tm
  38. struct tm dectm;
  39. gmtime_r(ts, &dectm);
  40. ltm = &dectm;
  41. }
  42. if (!ltm) // Paranoia
  43. return;
  44. if (mjd) { // Encode ymd into mjd
  45. int Y = ltm->tm_year; // 1900 + Y gives the real year
  46. int M = ltm->tm_mon + 1;
  47. int D = ltm->tm_mday;
  48. int L = (M == 1 || M == 2) ? 1 : 0;
  49. *mjd = 14956 + D + (int)((Y - L) * 365.25) + (int)((M + 1 + L * 12) * 30.6001);
  50. }
  51. if (bcd) { // Encode hms into bcd
  52. *bcd = 0;
  53. *bcd = dec2bcd(ltm->tm_hour) << 16;
  54. *bcd |= dec2bcd(ltm->tm_min ) << 8;
  55. *bcd |= dec2bcd(ltm->tm_sec );
  56. }
  57. }
  58. time_t ts_time_decode_mjd(uint16_t mjd, uint32_t bcd, struct tm *tm) {
  59. int year = 0, month = 0, day = 0;
  60. int hour = 0, min = 0, sec = 0;
  61. time_t ret = 0;
  62. if (mjd > 0) {
  63. long tmp;
  64. // Copied from ETSI EN 300 468 (ANNEX C)
  65. year = (int)((mjd - 15078.2) / 365.25);
  66. month = (int)((mjd - 14956.1 - (int)(year * 365.25)) / 30.6001);
  67. day = mjd - 14956 - (int)(year * 365.25) - (int)(month * 30.6001);
  68. tmp = (month == 14 || month == 15) ? 1 : 0;
  69. year = year + tmp;
  70. month = month - 1 - tmp * 12;
  71. year += 1900;
  72. }
  73. if (bcd > 0) {
  74. ts_time_decode_bcd(bcd, NULL, &hour, &min, &sec);
  75. }
  76. if (tm) {
  77. memset(tm, 0, sizeof(struct tm));
  78. tm->tm_year = year - 1900;
  79. tm->tm_mon = month - 1;
  80. tm->tm_mday = day;
  81. tm->tm_hour = hour;
  82. tm->tm_min = min;
  83. tm->tm_sec = sec;
  84. ret = timegm(tm);
  85. }
  86. return ret;
  87. }