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

time.c 2.3KB

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