PageRenderTime 26ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/src/input/mpegts/iptv/iptv.c

https://github.com/ngilles/tvheadend
C | 557 lines | 402 code | 81 blank | 74 comment | 40 complexity | 16c108b82f80cd641604b36d41954044 MD5 | raw file
  1. /*
  2. * IPTV Input
  3. *
  4. * Copyright (C) 2013 Andreas Ă–man
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "iptv_private.h"
  20. #include "tvhpoll.h"
  21. #include "tcp.h"
  22. #include "settings.h"
  23. #include <sys/socket.h>
  24. #include <sys/types.h>
  25. #include <sys/ioctl.h>
  26. #include <fcntl.h>
  27. #include <assert.h>
  28. #include <string.h>
  29. #include <regex.h>
  30. #include <unistd.h>
  31. #include <regex.h>
  32. #include <errno.h>
  33. #include <signal.h>
  34. #include <pthread.h>
  35. /* **************************************************************************
  36. * IPTV state
  37. * *************************************************************************/
  38. iptv_input_t *iptv_input;
  39. tvhpoll_t *iptv_poll;
  40. pthread_t iptv_thread;
  41. pthread_mutex_t iptv_lock;
  42. /* **************************************************************************
  43. * IPTV handlers
  44. * *************************************************************************/
  45. static RB_HEAD(,iptv_handler) iptv_handlers;
  46. static int
  47. ih_cmp ( iptv_handler_t *a, iptv_handler_t *b )
  48. {
  49. return strcasecmp(a->scheme, b->scheme);
  50. }
  51. void
  52. iptv_handler_register ( iptv_handler_t *ih, int num )
  53. {
  54. iptv_handler_t *r;
  55. while (num) {
  56. r = RB_INSERT_SORTED(&iptv_handlers, ih, link, ih_cmp);
  57. if (r)
  58. tvhwarn("iptv", "attempt to re-register handler for %s",
  59. ih->scheme);
  60. num--;
  61. ih++;
  62. }
  63. }
  64. static iptv_handler_t *
  65. iptv_handler_find ( const char *scheme )
  66. {
  67. iptv_handler_t ih;
  68. ih.scheme = scheme;
  69. return RB_FIND(&iptv_handlers, &ih, link, ih_cmp);
  70. }
  71. /* **************************************************************************
  72. * IPTV input
  73. * *************************************************************************/
  74. static const char *
  75. iptv_input_class_get_title ( idnode_t *self )
  76. {
  77. return "IPTV";
  78. }
  79. extern const idclass_t mpegts_input_class;
  80. const idclass_t iptv_input_class = {
  81. .ic_super = &mpegts_input_class,
  82. .ic_class = "iptv_input",
  83. .ic_caption = "IPTV Input",
  84. .ic_get_title = iptv_input_class_get_title,
  85. .ic_properties = (const property_t[]){
  86. {}
  87. }
  88. };
  89. static int
  90. iptv_input_is_free ( mpegts_input_t *mi )
  91. {
  92. int c = 0;
  93. mpegts_mux_instance_t *mmi;
  94. mpegts_network_link_t *mnl;
  95. LIST_FOREACH(mmi, &mi->mi_mux_active, mmi_active_link)
  96. c++;
  97. /* Limit reached */
  98. LIST_FOREACH(mnl, &mi->mi_networks, mnl_mi_link) {
  99. iptv_network_t *in = (iptv_network_t*)mnl->mnl_network;
  100. if (in->in_max_streams && c >= in->in_max_streams)
  101. return 0;
  102. }
  103. /* Bandwidth reached */
  104. LIST_FOREACH(mnl, &mi->mi_networks, mnl_mi_link) {
  105. iptv_network_t *in = (iptv_network_t*)mnl->mnl_network;
  106. if (in->in_bw_limited)
  107. return 0;
  108. }
  109. return 1;
  110. }
  111. static int
  112. iptv_input_get_weight ( mpegts_input_t *mi )
  113. {
  114. int c = 0, w = 0;
  115. const th_subscription_t *ths;
  116. const service_t *s;
  117. const mpegts_mux_instance_t *mmi;
  118. LIST_FOREACH(mmi, &mi->mi_mux_active, mmi_active_link)
  119. c++;
  120. /* Find the "min" weight */
  121. if (!iptv_input_is_free(mi)) {
  122. w = 1000000;
  123. /* Direct subs */
  124. LIST_FOREACH(mmi, &mi->mi_mux_active, mmi_active_link) {
  125. LIST_FOREACH(ths, &mmi->mmi_subs, ths_mmi_link) {
  126. w = MIN(w, ths->ths_weight);
  127. }
  128. }
  129. /* Service subs */
  130. pthread_mutex_lock(&mi->mi_output_lock);
  131. LIST_FOREACH(s, &mi->mi_transports, s_active_link) {
  132. LIST_FOREACH(ths, &s->s_subscriptions, ths_service_link) {
  133. w = MIN(w, ths->ths_weight);
  134. }
  135. }
  136. pthread_mutex_unlock(&mi->mi_output_lock);
  137. }
  138. return w;
  139. }
  140. static int
  141. iptv_input_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi )
  142. {
  143. int ret = SM_CODE_TUNING_FAILED;
  144. iptv_mux_t *im = (iptv_mux_t*)mmi->mmi_mux;
  145. iptv_handler_t *ih;
  146. char buf[256];
  147. url_t url;
  148. /* Already active */
  149. if (im->mm_active)
  150. return 0;
  151. /* Do we need to stop something? */
  152. if (!iptv_input_is_free(mi)) {
  153. pthread_mutex_lock(&mi->mi_output_lock);
  154. mpegts_mux_instance_t *m, *s = NULL;
  155. int w = 1000000;
  156. LIST_FOREACH(m, &mi->mi_mux_active, mmi_active_link) {
  157. int t = mpegts_mux_instance_weight(m);
  158. if (t < w) {
  159. s = m;
  160. w = t;
  161. }
  162. }
  163. pthread_mutex_unlock(&mi->mi_output_lock);
  164. /* Stop */
  165. if (s)
  166. s->mmi_mux->mm_stop(s->mmi_mux, 1);
  167. }
  168. /* Parse URL */
  169. im->mm_display_name((mpegts_mux_t*)im, buf, sizeof(buf));
  170. if (urlparse(im->mm_iptv_url ?: "", &url)) {
  171. tvherror("iptv", "%s - invalid URL [%s]", buf, im->mm_iptv_url);
  172. return ret;
  173. }
  174. /* Find scheme handler */
  175. ih = iptv_handler_find(url.scheme);
  176. if (!ih) {
  177. tvherror("iptv", "%s - unsupported scheme [%s]", buf, url.scheme);
  178. return ret;
  179. }
  180. /* Start */
  181. pthread_mutex_lock(&iptv_lock);
  182. im->mm_active = mmi; // Note: must set here else mux_started call
  183. // will not realise we're ready to accept pid open calls
  184. ret = ih->start(im, &url);
  185. if (!ret)
  186. im->im_handler = ih;
  187. else
  188. im->mm_active = NULL;
  189. pthread_mutex_unlock(&iptv_lock);
  190. return ret;
  191. }
  192. static void
  193. iptv_input_stop_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi )
  194. {
  195. iptv_mux_t *im = (iptv_mux_t*)mmi->mmi_mux;
  196. mpegts_network_link_t *mnl;
  197. // Not active??
  198. if (!im->mm_active)
  199. return;
  200. /* Stop */
  201. if (im->im_handler->stop)
  202. im->im_handler->stop(im);
  203. pthread_mutex_lock(&iptv_lock);
  204. /* Close file */
  205. if (im->mm_iptv_fd > 0) {
  206. close(im->mm_iptv_fd); // removes from poll
  207. im->mm_iptv_fd = -1;
  208. }
  209. /* Free memory */
  210. sbuf_free(&im->mm_iptv_buffer);
  211. /* Clear bw limit */
  212. LIST_FOREACH(mnl, &mi->mi_networks, mnl_mi_link) {
  213. iptv_network_t *in = (iptv_network_t*)mnl->mnl_network;
  214. in->in_bw_limited = 0;
  215. }
  216. pthread_mutex_unlock(&iptv_lock);
  217. }
  218. static void
  219. iptv_input_display_name ( mpegts_input_t *mi, char *buf, size_t len )
  220. {
  221. snprintf(buf, len, "IPTV");
  222. }
  223. static void *
  224. iptv_input_thread ( void *aux )
  225. {
  226. int nfds;
  227. ssize_t n;
  228. size_t off;
  229. iptv_mux_t *im;
  230. tvhpoll_event_t ev;
  231. while ( tvheadend_running ) {
  232. nfds = tvhpoll_wait(iptv_poll, &ev, 1, -1);
  233. if ( nfds < 0 ) {
  234. if (tvheadend_running) {
  235. tvhlog(LOG_ERR, "iptv", "poll() error %s, sleeping 1 second",
  236. strerror(errno));
  237. sleep(1);
  238. }
  239. continue;
  240. } else if ( nfds == 0 ) {
  241. continue;
  242. }
  243. im = ev.data.ptr;
  244. pthread_mutex_lock(&iptv_lock);
  245. /* No longer active */
  246. if (!im->mm_active)
  247. goto done;
  248. /* Get data */
  249. off = 0;
  250. if ((n = im->im_handler->read(im, &off)) < 0) {
  251. tvhlog(LOG_ERR, "iptv", "read() error %s", strerror(errno));
  252. im->im_handler->stop(im);
  253. goto done;
  254. }
  255. iptv_input_recv_packets(im, n, off);
  256. done:
  257. pthread_mutex_unlock(&iptv_lock);
  258. }
  259. return NULL;
  260. }
  261. void
  262. iptv_input_recv_packets ( iptv_mux_t *im, ssize_t len, size_t off )
  263. {
  264. static time_t t1 = 0, t2;
  265. iptv_network_t *in = (iptv_network_t*)im->mm_network;
  266. in->in_bps += len * 8;
  267. time(&t2);
  268. if (t2 != t1) {
  269. if (in->in_max_bandwidth &&
  270. in->in_bps > in->in_max_bandwidth * 1024) {
  271. if (!in->in_bw_limited) {
  272. tvhinfo("iptv", "%s bandwidth limited exceeded",
  273. idnode_get_title(&in->mn_id));
  274. in->in_bw_limited = 1;
  275. }
  276. }
  277. in->in_bps = 0;
  278. t1 = t2;
  279. }
  280. /* Pass on */
  281. mpegts_input_recv_packets((mpegts_input_t*)iptv_input, im->mm_active,
  282. &im->mm_iptv_buffer, off, NULL, NULL);
  283. }
  284. void
  285. iptv_input_mux_started ( iptv_mux_t *im )
  286. {
  287. tvhpoll_event_t ev = { 0 };
  288. char buf[256];
  289. im->mm_display_name((mpegts_mux_t*)im, buf, sizeof(buf));
  290. /* Allocate input buffer */
  291. sbuf_init_fixed(&im->mm_iptv_buffer, IPTV_PKT_SIZE);
  292. /* Setup poll */
  293. if (im->mm_iptv_fd > 0) {
  294. ev.fd = im->mm_iptv_fd;
  295. ev.events = TVHPOLL_IN;
  296. ev.data.ptr = im;
  297. /* Error? */
  298. if (tvhpoll_add(iptv_poll, &ev, 1) == -1) {
  299. tvherror("iptv", "%s - failed to add to poll q", buf);
  300. close(im->mm_iptv_fd);
  301. im->mm_iptv_fd = -1;
  302. return;
  303. }
  304. }
  305. /* Install table handlers */
  306. mpegts_mux_t *mm = (mpegts_mux_t*)im;
  307. psi_tables_default(mm);
  308. if (im->mm_iptv_atsc) {
  309. psi_tables_atsc_t(mm);
  310. psi_tables_atsc_c(mm);
  311. } else
  312. psi_tables_dvb(mm);
  313. }
  314. /* **************************************************************************
  315. * IPTV network
  316. * *************************************************************************/
  317. static void
  318. iptv_network_class_delete ( idnode_t *in )
  319. {
  320. mpegts_network_t *mn = (mpegts_network_t*)in;
  321. /* Remove config */
  322. hts_settings_remove("input/iptv/networks/%s",
  323. idnode_uuid_as_str(in));
  324. /* delete */
  325. mpegts_network_delete(mn, 1);
  326. }
  327. extern const idclass_t mpegts_network_class;
  328. const idclass_t iptv_network_class = {
  329. .ic_super = &mpegts_network_class,
  330. .ic_class = "iptv_network",
  331. .ic_caption = "IPTV Network",
  332. .ic_delete = iptv_network_class_delete,
  333. .ic_properties = (const property_t[]){
  334. {
  335. .type = PT_U32,
  336. .id = "max_streams",
  337. .name = "Max Input Streams",
  338. .off = offsetof(iptv_network_t, in_max_streams),
  339. .def.i = 0,
  340. },
  341. {
  342. .type = PT_U32,
  343. .id = "max_bandwidth",
  344. .name = "Max Bandwidth (Kbps)",
  345. .off = offsetof(iptv_network_t, in_max_bandwidth),
  346. .def.i = 0,
  347. },
  348. {}
  349. }
  350. };
  351. static mpegts_mux_t *
  352. iptv_network_create_mux2
  353. ( mpegts_network_t *mn, htsmsg_t *conf )
  354. {
  355. return (mpegts_mux_t*)iptv_mux_create0((iptv_network_t*)mn, NULL, conf);
  356. }
  357. static mpegts_service_t *
  358. iptv_network_create_service
  359. ( mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid )
  360. {
  361. return (mpegts_service_t*)
  362. iptv_service_create0((iptv_mux_t*)mm, sid, pmt_pid, NULL, NULL);
  363. }
  364. static const idclass_t *
  365. iptv_network_mux_class ( mpegts_network_t *mm )
  366. {
  367. extern const idclass_t iptv_mux_class;
  368. return &iptv_mux_class;
  369. }
  370. static void
  371. iptv_network_config_save ( mpegts_network_t *mn )
  372. {
  373. htsmsg_t *c = htsmsg_create_map();
  374. idnode_save(&mn->mn_id, c);
  375. hts_settings_save(c, "input/iptv/networks/%s/config",
  376. idnode_uuid_as_str(&mn->mn_id));
  377. htsmsg_destroy(c);
  378. }
  379. iptv_network_t *
  380. iptv_network_create0
  381. ( const char *uuid, htsmsg_t *conf )
  382. {
  383. iptv_network_t *in;
  384. htsmsg_t *c;
  385. /* Init Network */
  386. if (!(in = mpegts_network_create(iptv_network, uuid, NULL, conf)))
  387. return NULL;
  388. in->mn_create_service = iptv_network_create_service;
  389. in->mn_mux_class = iptv_network_mux_class;
  390. in->mn_mux_create2 = iptv_network_create_mux2;
  391. in->mn_config_save = iptv_network_config_save;
  392. /* Defaults */
  393. if (!conf) {
  394. in->mn_skipinitscan = 1;
  395. }
  396. /* Link */
  397. mpegts_input_add_network((mpegts_input_t*)iptv_input, (mpegts_network_t*)in);
  398. /* Load muxes */
  399. if ((c = hts_settings_load_r(1, "input/iptv/networks/%s/muxes",
  400. idnode_uuid_as_str(&in->mn_id)))) {
  401. htsmsg_field_t *f;
  402. htsmsg_t *e;
  403. HTSMSG_FOREACH(f, c) {
  404. if (!(e = htsmsg_get_map_by_field(f))) continue;
  405. if (!(e = htsmsg_get_map(e, "config"))) continue;
  406. iptv_mux_create0(in, f->hmf_name, e);
  407. }
  408. htsmsg_destroy(c);
  409. }
  410. return in;
  411. }
  412. static mpegts_network_t *
  413. iptv_network_builder
  414. ( const idclass_t *idc, htsmsg_t *conf )
  415. {
  416. return (mpegts_network_t*)iptv_network_create0(NULL, conf);
  417. }
  418. /* **************************************************************************
  419. * IPTV initialise
  420. * *************************************************************************/
  421. static void
  422. iptv_network_init ( void )
  423. {
  424. htsmsg_t *c, *e;
  425. htsmsg_field_t *f;
  426. /* Register builder */
  427. mpegts_network_register_builder(&iptv_network_class,
  428. iptv_network_builder);
  429. /* Load settings */
  430. if (!(c = hts_settings_load_r(1, "input/iptv/networks")))
  431. return;
  432. HTSMSG_FOREACH(f, c) {
  433. if (!(e = htsmsg_get_map_by_field(f))) continue;
  434. if (!(e = htsmsg_get_map(e, "config"))) continue;
  435. iptv_network_create0(f->hmf_name, e);
  436. }
  437. htsmsg_destroy(c);
  438. }
  439. void iptv_init ( void )
  440. {
  441. /* Register handlers */
  442. iptv_http_init();
  443. iptv_udp_init();
  444. iptv_input = calloc(1, sizeof(iptv_input_t));
  445. /* Init Input */
  446. mpegts_input_create0((mpegts_input_t*)iptv_input,
  447. &iptv_input_class, NULL, NULL);
  448. iptv_input->mi_start_mux = iptv_input_start_mux;
  449. iptv_input->mi_stop_mux = iptv_input_stop_mux;
  450. iptv_input->mi_is_free = iptv_input_is_free;
  451. iptv_input->mi_get_weight = iptv_input_get_weight;
  452. iptv_input->mi_display_name = iptv_input_display_name;
  453. iptv_input->mi_enabled = 1;
  454. /* Init Network */
  455. iptv_network_init();
  456. /* Setup TS thread */
  457. iptv_poll = tvhpoll_create(10);
  458. pthread_mutex_init(&iptv_lock, NULL);
  459. tvhthread_create(&iptv_thread, NULL, iptv_input_thread, NULL, 0);
  460. }
  461. void iptv_done ( void )
  462. {
  463. pthread_kill(iptv_thread, SIGTERM);
  464. pthread_join(iptv_thread, NULL);
  465. tvhpoll_destroy(iptv_poll);
  466. pthread_mutex_lock(&global_lock);
  467. mpegts_network_unregister_builder(&iptv_network_class);
  468. mpegts_input_stop_all((mpegts_input_t*)iptv_input);
  469. mpegts_input_delete((mpegts_input_t *)iptv_input, 0);
  470. pthread_mutex_unlock(&global_lock);
  471. }
  472. /******************************************************************************
  473. * Editor Configuration
  474. *
  475. * vim:sts=2:ts=2:sw=2:et
  476. *****************************************************************************/