vbi.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942
  1. #define _GNU_SOURCE
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <fcntl.h>
  6. #include <stdio.h>
  7. #include <errno.h>
  8. #include <stdarg.h>
  9. #include <sys/ioctl.h>
  10. #include <sys/poll.h>
  11. #include "os.h"
  12. #include "vt.h"
  13. #include "misc.h"
  14. #include "vbi.h"
  15. #include "fdset.h"
  16. #include "hamm.h"
  17. #include "lang.h"
  18. #include <libzvbi.h>
  19. static vbi_capture * pZvbiCapt;
  20. static vbi_raw_decoder * pZvbiRawDec;
  21. static vbi_sliced * pZvbiData;
  22. static vbi_proxy_client * pProxy;
  23. #define ZVBI_BUFFER_COUNT 10
  24. #define ZVBI_TRACE 0
  25. static int vbi_dvb_open(struct vbi *vbi, const char *vbi_name,
  26. const char *channel, char *outfile, u_int16_t sid, int ttpid);
  27. static void dvb_handler(struct vbi *vbi, int fd);
  28. #define FAC (1<<16) // factor for fix-point arithmetic
  29. static u8 *rawbuf; // one common buffer for raw vbi data
  30. static int rawbuf_size; // its current size
  31. u_int16_t sid;
  32. static char *vbi_names[]
  33. = { "/dev/vbi", "/dev/vbi0", "/dev/video0", "/dev/dvb/adapter0/demux0",
  34. NULL }; // default device names if none was given at the command line
  35. static void out_of_sync(struct vbi *vbi)
  36. {
  37. int i; // discard all in progress pages
  38. for (i = 0; i < 8; ++i)
  39. vbi->rpage[i].page->flags &= ~PG_ACTIVE;
  40. }
  41. // send an event to all clients
  42. static void vbi_send(struct vbi *vbi, int type, int i1, int i2, int i3, void *p1)
  43. {
  44. struct vt_event ev[1];
  45. struct vbi_client *cl, *cln;
  46. ev->resource = vbi;
  47. ev->type = type;
  48. ev->i1 = i1;
  49. ev->i2 = i2;
  50. ev->i3 = i3;
  51. ev->p1 = p1;
  52. for (cl = PTR vbi->clients->first; cln = PTR cl->node->next; cl = cln)
  53. cl->handler(cl->data, ev);
  54. }
  55. static void vbi_send_page(struct vbi *vbi, struct raw_page *rvtp, int page)
  56. {
  57. struct vt_page *cvtp = 0;
  58. if (rvtp->page->flags & PG_ACTIVE)
  59. {
  60. if (rvtp->page->pgno % 256 != page)
  61. {
  62. rvtp->page->flags &= ~PG_ACTIVE;
  63. enhance(rvtp->enh, rvtp->page);
  64. if (vbi->cache)
  65. cvtp = vbi->cache->op->put(vbi->cache, rvtp->page);
  66. vbi_send(vbi, EV_PAGE, 0, 0, 0, cvtp ?: rvtp->page);
  67. }
  68. }
  69. }
  70. static void pll_add(struct vbi *vbi, int n, int err)
  71. {
  72. }
  73. // process one videotext packet
  74. static int vt_line(struct vbi *vbi, u8 *p)
  75. {
  76. struct vt_page *cvtp;
  77. struct raw_page *rvtp;
  78. int hdr, mag, mag8, pkt, i;
  79. int err = 0;
  80. hdr = hamm16(p, &err);
  81. if (err & 0xf000)
  82. return -4;
  83. mag = hdr & 7;
  84. mag8 = mag?: 8;
  85. pkt = (hdr >> 3) & 0x1f;
  86. p += 2;
  87. rvtp = vbi->rpage + mag;
  88. cvtp = rvtp->page;
  89. switch (pkt)
  90. {
  91. case 0:
  92. {
  93. int b1, b2, b3, b4;
  94. b1 = hamm16(p, &err); // page number
  95. b2 = hamm16(p+2, &err); // subpage number + flags
  96. b3 = hamm16(p+4, &err); // subpage number + flags
  97. b4 = hamm16(p+6, &err); // language code + more flags
  98. if (vbi->ppage->page->flags & PG_MAGSERIAL)
  99. vbi_send_page(vbi, vbi->ppage, b1);
  100. vbi_send_page(vbi, rvtp, b1);
  101. if (err & 0xf000)
  102. return 4;
  103. cvtp->errors = (err >> 8) + chk_parity(p + 8, 32);;
  104. cvtp->pgno = mag8 * 256 + b1;
  105. cvtp->subno = (b2 + b3 * 256) & 0x3f7f;
  106. cvtp->lang = "\0\4\2\6\1\5\3\7"[b4 >> 5] + (latin1==LATIN1 ? 0 : 8);
  107. cvtp->flags = b4 & 0x1f;
  108. cvtp->flags |= b3 & 0xc0;
  109. cvtp->flags |= (b2 & 0x80) >> 2;
  110. cvtp->lines = 1;
  111. cvtp->flof = 0;
  112. vbi->ppage = rvtp;
  113. pll_add(vbi, 1, cvtp->errors);
  114. conv2latin(p + 8, 32, cvtp->lang);
  115. vbi_send(vbi, EV_HEADER, cvtp->pgno, cvtp->subno, cvtp->flags, p);
  116. if (b1 == 0xff)
  117. return 0;
  118. cvtp->flags |= PG_ACTIVE;
  119. init_enhance(rvtp->enh);
  120. memcpy(cvtp->data[0]+0, p, 40);
  121. memset(cvtp->data[0]+40, ' ', sizeof(cvtp->data)-40);
  122. return 0;
  123. }
  124. case 1 ... 24:
  125. {
  126. pll_add(vbi, 1, err = chk_parity(p, 40));
  127. if (~cvtp->flags & PG_ACTIVE)
  128. return 0;
  129. cvtp->errors += err;
  130. cvtp->lines |= 1 << pkt;
  131. conv2latin(p, 40, cvtp->lang);
  132. memcpy(cvtp->data[pkt], p, 40);
  133. return 0;
  134. }
  135. case 26:
  136. {
  137. int d, t[13];
  138. if (~cvtp->flags & PG_ACTIVE)
  139. return 0;
  140. d = hamm8(p, &err);
  141. if (err & 0xf000)
  142. return 4;
  143. for (i = 0; i < 13; ++i)
  144. t[i] = hamm24(p + 1 + 3*i, &err);
  145. if (err & 0xf000)
  146. return 4;
  147. add_enhance(rvtp->enh, d, t);
  148. return 0;
  149. }
  150. case 27:
  151. {
  152. int b1,b2,b3,x;
  153. if (~cvtp->flags & PG_ACTIVE)
  154. return 0; // -1 flushes all pages. We may never resync again
  155. b1 = hamm8(p, &err);
  156. b2 = hamm8(p + 37, &err);
  157. if (err & 0xf000)
  158. return 4;
  159. if (b1 != 0 || not(b2 & 8))
  160. return 0;
  161. for (i = 0; i < 6; ++i)
  162. {
  163. err = 0;
  164. b1 = hamm16(p+1+6*i, &err);
  165. b2 = hamm16(p+3+6*i, &err);
  166. b3 = hamm16(p+5+6*i, &err);
  167. if (err & 0xf000)
  168. return 1;
  169. x = (b2 >> 7) | ((b3 >> 5) & 0x06);
  170. cvtp->link[i].pgno = ((mag ^ x) ?: 8) * 256 + b1;
  171. cvtp->link[i].subno = (b2 + b3 * 256) & 0x3f7f;
  172. }
  173. cvtp->flof = 1;
  174. return 0;
  175. }
  176. case 30:
  177. {
  178. if (mag8 != 8)
  179. return 0;
  180. p[0] = hamm8(p, &err); // designation code
  181. p[1] = hamm16(p+1, &err); // initial page
  182. p[3] = hamm16(p+3, &err); // initial subpage + mag
  183. p[5] = hamm16(p+5, &err); // initial subpage + mag
  184. if (err & 0xf000)
  185. return 4;
  186. err += chk_parity(p+20, 20);
  187. conv2latin(p+20, 20, 0);
  188. vbi_send(vbi, EV_XPACKET, mag8, pkt, err, p);
  189. return 0;
  190. }
  191. default:
  192. return 0;
  193. }
  194. return 0;
  195. }
  196. // called when new vbi data is waiting
  197. static void vbi_handler(struct vbi *vbi, int fd)
  198. {
  199. double timestamp;
  200. struct timeval timeout;
  201. int lineCount;
  202. int line;
  203. int res;
  204. timeout.tv_sec = 0;
  205. timeout.tv_usec = 25000;
  206. res = vbi_capture_read_sliced(pZvbiCapt, pZvbiData, &lineCount, &timestamp,
  207. &timeout);
  208. if (res > 0)
  209. {
  210. for (line=0; line < lineCount; line++)
  211. {
  212. if ((pZvbiData[line].id & VBI_SLICED_TELETEXT_B) != 0)
  213. {
  214. vt_line(vbi, pZvbiData[line].data);
  215. }
  216. }
  217. }
  218. else if (res < 0)
  219. {
  220. }
  221. }
  222. int vbi_add_handler(struct vbi *vbi, void *handler, void *data)
  223. {
  224. struct vbi_client *cl;
  225. if (not(cl = malloc(sizeof(*cl))))
  226. return -1;
  227. cl->handler = handler;
  228. cl->data = data;
  229. dl_insert_last(vbi->clients, cl->node);
  230. return 0;
  231. }
  232. void vbi_del_handler(struct vbi *vbi, void *handler, void *data)
  233. {
  234. struct vbi_client *cl;
  235. for (cl = PTR vbi->clients->first; cl->node->next; cl = PTR cl->node->next)
  236. if (cl->handler == handler && cl->data == data)
  237. {
  238. dl_remove(cl->node);
  239. break;
  240. }
  241. return;
  242. }
  243. struct vbi * vbi_open(char *vbi_name, struct cache *ca,
  244. const char *channel, char *outfile, u_int16_t sid, int ttpid)
  245. {
  246. static int inited = 0;
  247. struct vbi *vbi;
  248. char * pErrStr;
  249. int services;
  250. if (vbi_name == NULL)
  251. {
  252. int i;
  253. char *tried_devices = NULL;
  254. char *old_tried_devices = NULL;
  255. for (i = 0; vbi_names[i] != NULL; i++)
  256. {
  257. vbi_name = vbi_names[i];
  258. // collect device names for the error message below
  259. if (old_tried_devices)
  260. {
  261. if (asprintf(&tried_devices, "%s, %s", old_tried_devices, vbi_name) < 0)
  262. tried_devices = NULL;
  263. free(old_tried_devices);
  264. }
  265. else if (asprintf(&tried_devices, "%s", vbi_name) < 0)
  266. tried_devices = NULL;
  267. if (tried_devices == NULL)
  268. out_of_mem(-1);
  269. old_tried_devices = tried_devices;
  270. if (access(vbi_name, R_OK) != 0)
  271. continue;
  272. vbi = vbi_open(vbi_name, ca, channel, outfile, sid, ttpid);
  273. if (vbi != NULL)
  274. {
  275. if (tried_devices != NULL)
  276. free(tried_devices);
  277. return vbi;
  278. }
  279. }
  280. error("could not open any of the standard devices (%s)", tried_devices);
  281. free(tried_devices);
  282. return NULL;
  283. }
  284. if (not inited)
  285. lang_init();
  286. inited = 1;
  287. if (not(vbi = malloc(sizeof(*vbi))))
  288. {
  289. error("out of memory");
  290. goto fail1;
  291. }
  292. if (!vbi_dvb_open(vbi, vbi_name, channel, outfile, sid, ttpid)) {
  293. vbi->cache = ca;
  294. dl_init(vbi->clients);
  295. out_of_sync(vbi);
  296. vbi->ppage = vbi->rpage;
  297. fdset_add_fd(fds, vbi->fd, dvb_handler, vbi);
  298. return vbi;
  299. }
  300. services = VBI_SLICED_TELETEXT_B;
  301. pErrStr = NULL;
  302. vbi->fd = -1;
  303. pProxy = vbi_proxy_client_create(vbi_name, "alevt",
  304. VBI_PROXY_CLIENT_NO_STATUS_IND, &pErrStr, ZVBI_TRACE);
  305. if (pProxy != NULL)
  306. {
  307. pZvbiCapt = vbi_capture_proxy_new(pProxy, ZVBI_BUFFER_COUNT, 0,
  308. &services, 0, &pErrStr);
  309. if (pZvbiCapt == NULL)
  310. {
  311. vbi_proxy_client_destroy(pProxy);
  312. pProxy = NULL;
  313. }
  314. }
  315. if (pZvbiCapt == NULL)
  316. pZvbiCapt = vbi_capture_v4l2_new(vbi_name, ZVBI_BUFFER_COUNT,
  317. &services, 0, &pErrStr, ZVBI_TRACE);
  318. if (pZvbiCapt == NULL)
  319. pZvbiCapt = vbi_capture_v4l_new(vbi_name, 0, &services, 0, &pErrStr,
  320. ZVBI_TRACE);
  321. if (pZvbiCapt != NULL)
  322. {
  323. pZvbiRawDec = vbi_capture_parameters(pZvbiCapt);
  324. if ((pZvbiRawDec != NULL) && ((services & VBI_SLICED_TELETEXT_B) != 0))
  325. {
  326. pZvbiData = malloc((pZvbiRawDec->count[0] + pZvbiRawDec->count[1]) \
  327. * sizeof(*pZvbiData));
  328. vbi->fd = vbi_capture_fd(pZvbiCapt);
  329. }
  330. else
  331. vbi_capture_delete(pZvbiCapt);
  332. }
  333. if (pErrStr != NULL)
  334. {
  335. fprintf(stderr, "libzvbi: %s\n", pErrStr);
  336. free(pErrStr);
  337. }
  338. if (vbi->fd == -1)
  339. goto fail2;
  340. vbi->cache = ca;
  341. dl_init(vbi->clients);
  342. out_of_sync(vbi);
  343. vbi->ppage = vbi->rpage;
  344. fdset_add_fd(fds, vbi->fd, vbi_handler, vbi);
  345. return vbi;
  346. fail3:
  347. close(vbi->fd);
  348. fail2:
  349. free(vbi);
  350. fail1:
  351. return 0;
  352. }
  353. void vbi_close(struct vbi *vbi)
  354. {
  355. fdset_del_fd(fds, vbi->fd);
  356. if (vbi->cache)
  357. vbi->cache->op->close(vbi->cache);
  358. if (pZvbiData != NULL)
  359. free(pZvbiData);
  360. pZvbiData = NULL;
  361. if (pZvbiCapt != NULL)
  362. {
  363. vbi_capture_delete(pZvbiCapt);
  364. pZvbiCapt = NULL;
  365. }
  366. if (pProxy != NULL)
  367. {
  368. vbi_proxy_client_destroy(pProxy);
  369. pProxy = NULL;
  370. }
  371. free(vbi);
  372. }
  373. struct vt_page * vbi_query_page(struct vbi *vbi, int pgno, int subno)
  374. {
  375. struct vt_page *vtp = 0;
  376. if (vbi->cache)
  377. vtp = vbi->cache->op->get(vbi->cache, pgno, subno);
  378. if (vtp == 0)
  379. {
  380. return 0;
  381. }
  382. vbi_send(vbi, EV_PAGE, 1, 0, 0, vtp);
  383. return vtp;
  384. }
  385. void vbi_reset(struct vbi *vbi)
  386. {
  387. if (vbi->cache)
  388. vbi->cache->op->reset(vbi->cache);
  389. vbi_send(vbi, EV_RESET, 0, 0, 0, 0);
  390. }
  391. /* Starting from here: DVB API */
  392. #include <linux/dvb/dmx.h>
  393. #include <linux/dvb/frontend.h>
  394. #include <linux/dvb/video.h>
  395. static int dvb_get_table(int fd, u_int16_t pid, u_int8_t tblid, u_int8_t *buf,
  396. size_t bufsz)
  397. {
  398. struct dmx_sct_filter_params sctFilterParams;
  399. struct pollfd pfd;
  400. int r;
  401. memset(&sctFilterParams, 0, sizeof(sctFilterParams));
  402. sctFilterParams.pid = pid;
  403. sctFilterParams.timeout = 10000;
  404. sctFilterParams.flags = DMX_ONESHOT | DMX_IMMEDIATE_START | DMX_CHECK_CRC;
  405. sctFilterParams.filter.filter[0] = tblid;
  406. sctFilterParams.filter.mask[0] = 0xff;
  407. if (ioctl(fd, DMX_SET_FILTER, &sctFilterParams)) {
  408. perror("DMX_SET_FILTER");
  409. return -1;
  410. }
  411. pfd.fd = fd;
  412. pfd.events = POLLIN;
  413. r = poll(&pfd, 1, 10000);
  414. if (r < 0) {
  415. perror("poll");
  416. goto out;
  417. }
  418. if (r > 0) {
  419. r = read(fd, buf, bufsz);
  420. if (r < 0) {
  421. perror("read");
  422. goto out;
  423. }
  424. }
  425. out:
  426. ioctl(fd, DMX_STOP, 0);
  427. return r;
  428. }
  429. static const u_int8_t byterev8[256] = {
  430. 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
  431. 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
  432. 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
  433. 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
  434. 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
  435. 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
  436. 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
  437. 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
  438. 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
  439. 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
  440. 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
  441. 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
  442. 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
  443. 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
  444. 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
  445. 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
  446. 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
  447. 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
  448. 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
  449. 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
  450. 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
  451. 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
  452. 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
  453. 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
  454. 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
  455. 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
  456. 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
  457. 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
  458. 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
  459. 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
  460. 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
  461. 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
  462. };
  463. static void dvb_handle_pes_payload(struct vbi *vbi, const u_int8_t *buf,
  464. unsigned int len)
  465. {
  466. unsigned int p, i;
  467. u_int8_t data[42];
  468. if (buf[0] < 0x10 || buf[0] > 0x1f)
  469. return; /* no EBU teletext data */
  470. for (p = 1; p < len; p += /*6 + 40*/ 2 + buf[p + 1]) {
  471. #if 0
  472. printf("Txt Line:\n"
  473. " data_unit_id 0x%02x\n"
  474. " data_unit_length 0x%02x\n"
  475. " reserved_for_future_use 0x%01x\n"
  476. " field_parity 0x%01x\n"
  477. " line_offset 0x%02x\n"
  478. " framing_code 0x%02x\n"
  479. " magazine_and_packet_addr 0x%04x\n"
  480. " data_block 0x%02x 0x%02x 0x%02x 0x%02x\n",
  481. buf[p], buf[p+1],
  482. buf[p+2] >> 6,
  483. (buf[p+2] >> 5) & 1,
  484. buf[p+2] & 0x1f,
  485. buf[p+3],
  486. (buf[p+4] << 8) | buf[p+5],
  487. buf[p+6], buf[p+7], buf[p+8], buf[p+9]);
  488. #endif
  489. for (i = 0; i < sizeof(data); i++)
  490. data[i] = byterev8[buf[p+4+i]];
  491. /* note: we should probably check for missing lines and then
  492. * call out_of_sync(vbi); and/or vbi_reset(vbi); */
  493. vt_line(vbi, data);
  494. }
  495. }
  496. static unsigned int rawptr;
  497. static void dvb_handler(struct vbi *vbi, int fd)
  498. {
  499. /* PES packet start code prefix and stream_id == private_stream_1 */
  500. static const u_int8_t peshdr[4] = { 0x00, 0x00, 0x01, 0xbd };
  501. u_int8_t *bp;
  502. int n;
  503. unsigned int p, i, len;
  504. u_int16_t rpid;
  505. u_int32_t crc, crccomp;
  506. if (rawptr >= (unsigned int)rawbuf_size)
  507. rawptr = 0;
  508. n = read(vbi->fd, rawbuf + rawptr, rawbuf_size - rawptr);
  509. if (n <= 0)
  510. return;
  511. rawptr += n;
  512. if (rawptr < 6)
  513. return;
  514. if (memcmp(rawbuf, peshdr, sizeof(peshdr))) {
  515. bp = memmem(rawbuf, rawptr, peshdr, sizeof(peshdr));
  516. if (!bp)
  517. return;
  518. rawptr -= (bp - rawbuf);
  519. memmove(rawbuf, bp, rawptr);
  520. if (rawptr < 6)
  521. return;
  522. }
  523. len = (rawbuf[4] << 8) | rawbuf[5];
  524. if (len < 9) {
  525. rawptr = 0;
  526. return;
  527. }
  528. if (rawptr < len + 6)
  529. return;
  530. p = 9 + rawbuf[8];
  531. #if 0
  532. for (i = 0; i < len - p; i++) {
  533. if (!(i & 15))
  534. printf("\n%04x:", i);
  535. printf(" %02x", rawbuf[p + i]);
  536. }
  537. printf("\n");
  538. #endif
  539. if (!dl_empty(vbi->clients))
  540. dvb_handle_pes_payload(vbi, rawbuf + p, len - p);
  541. rawptr -= len;
  542. if (rawptr)
  543. memmove(rawbuf, rawbuf + len, rawptr);
  544. }
  545. static int vbi_dvb_open(struct vbi *vbi, const char *vbi_name,
  546. const char *channel, char *outfile, u_int16_t sid, int ttpid)
  547. {
  548. struct {
  549. u_int16_t pmtpid;
  550. u_int16_t ttpid;
  551. u_int16_t service_id;
  552. u_int8_t service_type;
  553. char service_provider_name[64];
  554. char service_name[64];
  555. u_int8_t txtlang[3];
  556. u_int8_t txttype;
  557. u_int8_t txtmagazine;
  558. u_int8_t txtpage;
  559. } progtbl[16], *progp;
  560. u_int8_t tbl[4096];
  561. u_int8_t * ppname, * psname, pncode, sncode, pnlen, snlen;
  562. int r;
  563. FILE *ofd;
  564. unsigned int i, j, k, l, progcnt = 0;
  565. struct dmx_pes_filter_params filterpar;
  566. /* open DVB demux device */
  567. if (!vbi_name)
  568. vbi_name = "/dev/dvb/adapter0/demux0";
  569. if ((vbi->fd = open(vbi_name, O_RDWR)) == -1) {
  570. error("cannot open demux device %s", vbi_name);
  571. return -1;
  572. }
  573. memset(progtbl, 0, sizeof(progtbl));
  574. if (ttpid >= 0x15 && ttpid < 0x1fff) {
  575. vbi->ttpid = ttpid;
  576. printf("Using command line specified teletext PID 0x%x\n",
  577. vbi->ttpid);
  578. goto ttpidfound;
  579. }
  580. /* parse PAT to enumerate services and to find the PMT PIDs */
  581. r = dvb_get_table(vbi->fd, 0, 0, tbl, sizeof(tbl));
  582. if (r == -1)
  583. goto outerr;
  584. if (!(tbl[5] & 1)) {
  585. error("PAT not active (current_next_indicator == 0)");
  586. goto outerr;
  587. }
  588. if (tbl[6] != 0 || tbl[7] != 0) {
  589. error("PAT has multiple sections");
  590. goto outerr;
  591. }
  592. if (r < 13) {
  593. error("PAT too short\n");
  594. goto outerr;
  595. }
  596. r -= 13;
  597. for (i = 0; i < (unsigned)r; i += 4) {
  598. if (progcnt >= sizeof(progtbl)/sizeof(progtbl[0])) {
  599. error("Program table overflow");
  600. goto outerr;
  601. }
  602. progtbl[progcnt].service_id = (tbl[8 + i] << 8) | tbl[9 + i];
  603. if (!progtbl[progcnt].service_id) /* this is the NIT pointer */
  604. continue;
  605. progtbl[progcnt].pmtpid = ((tbl[10 + i] << 8) | tbl[11 + i])
  606. & 0x1fff;
  607. progcnt++;
  608. }
  609. /* find the SDT to get the station names */
  610. r = dvb_get_table(vbi->fd, 0x11, 0x42, tbl, sizeof(tbl));
  611. if (r == -1)
  612. goto outerr;
  613. if (!(tbl[5] & 1)) {
  614. error("SDT not active (current_next_indicator == 0)");
  615. goto outerr;
  616. }
  617. if (tbl[6] != 0 || tbl[7] != 0) {
  618. error("SDT has multiple sections");
  619. goto outerr;
  620. }
  621. if (r < 12) {
  622. error("SDT too short\n");
  623. goto outerr;
  624. }
  625. i = 11;
  626. while (i < (unsigned)r - 1) {
  627. k = (tbl[i] << 8) | tbl[i+1]; /* service ID */
  628. progp = NULL;
  629. for (j = 0; j < progcnt; j++)
  630. if (progtbl[j].service_id == k) {
  631. progp = &progtbl[j];
  632. break;
  633. }
  634. j = i + 5;
  635. i = j + (((tbl[i+3] << 8) | tbl[i+4]) & 0x0fff);
  636. if (!progp) {
  637. error("SDT: service_id 0x%x not in PAT\n", k);
  638. continue;
  639. }
  640. while (j < i) {
  641. switch (tbl[j]) {
  642. case 0x48: // service descriptor
  643. k = j + 4 + tbl[j + 3];
  644. progp->service_type = tbl[j+2];
  645. ppname = tbl+j+4 ; // points to 1st byte of provider_name
  646. pncode = *ppname ; // 1st byte of provider_name
  647. pnlen = tbl[j+3]; // length of provider_name
  648. psname = tbl+k+1 ; // points to 1st byte of service_name
  649. sncode = *psname ; // 1st byte of service_name
  650. snlen = tbl[k] ; // length of service_name
  651. if (pncode >= 0x20) {
  652. pncode = 0 ; // default character set Latin alphabet fig.A.1
  653. } else {
  654. ppname++ ; pnlen-- ;
  655. // character code from table A.3 1st byte = ctrl-code
  656. }
  657. if (sncode >= 0x20) {
  658. sncode = 0 ; // default character set Latin alphabet fig.A.1
  659. } else {
  660. psname++ ; snlen-- ;
  661. // character code from table A.3 ; 1st byte = ctrl-code
  662. }
  663. snprintf(progp->service_provider_name,
  664. sizeof(progp->service_provider_name), "%.*s", pnlen, ppname);
  665. snprintf(progp->service_name,
  666. sizeof(progp->service_name), "%.*s", snlen, psname); break;
  667. }
  668. j += 2 + tbl[j + 1]; // next descriptor
  669. }
  670. }
  671. /* parse PMT's to find Teletext Services */
  672. for (l = 0; l < progcnt; l++) {
  673. progtbl[l].ttpid = 0x1fff;
  674. if (progtbl[l].service_type != 0x01 || /* not digital TV */
  675. progtbl[l].pmtpid < 0x15 || /* PMT PID sanity check */
  676. progtbl[l].pmtpid >= 0x1fff)
  677. continue;
  678. r = dvb_get_table(vbi->fd, progtbl[l].pmtpid, 0x02, tbl,
  679. sizeof(tbl));
  680. if (r == -1)
  681. goto outerr;
  682. if (!(tbl[5] & 1)) { error \
  683. ("PMT pid 0x%x not active (current_next_indicator == 0)",
  684. progtbl[l].pmtpid);
  685. goto outerr;
  686. }
  687. if (tbl[6] != 0 || tbl[7] != 0) {
  688. error("PMT pid 0x%x has multiple sections",
  689. progtbl[l].pmtpid);
  690. goto outerr;
  691. }
  692. if (r < 13) {
  693. error("PMT pid 0x%x too short\n", progtbl[l].pmtpid);
  694. goto outerr;
  695. }
  696. i = 12 + (((tbl[10] << 8) | tbl[11]) & 0x0fff);
  697. /* skip program info section */
  698. while (i <= (unsigned)r-6) {
  699. j = i + 5;
  700. i = j + (((tbl[i + 3] << 8) | tbl[i + 4]) & 0x0fff);
  701. if (tbl[j - 5] != 0x06)
  702. /* teletext streams have type 0x06 */
  703. continue;
  704. k = ((tbl[j - 4] << 8) | tbl[j - 3]) & 0x1fff;
  705. /* elementary PID - save until we know if it's teletext PID */
  706. while (j < i) {
  707. switch (tbl[j]) {
  708. case 0x56: /* EBU teletext descriptor */
  709. progtbl[l].txtlang[0] = tbl[j + 2];
  710. progtbl[l].txtlang[1] = tbl[j + 3];
  711. progtbl[l].txtlang[2] = tbl[j + 4];
  712. progtbl[l].txttype = tbl[j + 5] >> 3;
  713. progtbl[l].txtmagazine = tbl[j + 5] & 7;
  714. progtbl[l].txtpage = tbl[j + 6];
  715. progtbl[l].ttpid = k;
  716. break;
  717. }
  718. j += 2 + tbl[j + 1];
  719. }
  720. }
  721. }
  722. printf \
  723. ("sid:pmtpid:ttpid:type:provider:name:language:texttype:magazine:page\n\n");
  724. for (i = 0; i < progcnt; i++) {
  725. printf("%d:%d:%d:%d:%s:%s:lang=%.3s:type=%d:magazine=%1u:page=%3u\n",
  726. progtbl[i].service_id, progtbl[i].pmtpid, progtbl[i].ttpid,
  727. progtbl[i].service_type, progtbl[i].service_provider_name,
  728. progtbl[i].service_name, progtbl[i].txtlang, progtbl[i].txttype,
  729. progtbl[i].txtmagazine, progtbl[i].txtpage);
  730. }
  731. if (*outfile) {
  732. ofd = fopen(outfile,"w") ;
  733. if (ofd == NULL) { error("cannot open outfile\n"); goto outerr ; }
  734. for (i = 0; i < progcnt; i++) {
  735. if (progtbl[i].ttpid == 0x1fff) continue ; // service without teletext
  736. fprintf(ofd,"%d:%d:%s:%s:lang=%.3s\n",
  737. progtbl[i].service_id, progtbl[i].ttpid, progtbl[i].service_provider_name,
  738. progtbl[i].service_name, progtbl[i].txtlang);
  739. }
  740. fclose(ofd) ;
  741. }
  742. progp = NULL;
  743. if (channel) {
  744. j = strlen(channel);
  745. for (i = 0; i < progcnt; i++)
  746. if (!strncmp(progtbl[i].service_name, channel, j)
  747. && progtbl[i].ttpid != 0x1fff) { progp = &progtbl[i];
  748. break ;
  749. }
  750. }
  751. if (channel && !progp) {
  752. j = strlen(channel);
  753. for (i = 0; i < progcnt; i++)
  754. if (!strncasecmp(progtbl[i].service_name, channel, j)
  755. && progtbl[i].ttpid != 0x1fff) { progp = &progtbl[i];
  756. break ;
  757. }
  758. }
  759. if (sid) {
  760. for (i = 0; i < progcnt; i++) {
  761. if ((progtbl[i].service_id == sid) && (progtbl[i].ttpid != 0x1fff)) {
  762. progp = &progtbl[i]; break ; }
  763. }
  764. }
  765. if (!progp) {
  766. for (i = 0; i < progcnt; i++)
  767. if (progtbl[i].ttpid != 0x1fff) {
  768. progp = &progtbl[i]; break ;
  769. }
  770. }
  771. printf("\nUsing: Service ID = %d ; PMT PID = %d ; TXT PID = %d ;\n"
  772. "Service type = %d ; Provider Name = %s ; Service name = %s ;\n"
  773. "language = %.3s ; Text type = %d ; Text Magazine = %1u ; Text page = %3u\n",
  774. progp->service_id, progp->pmtpid, progp->ttpid, progp->service_type,
  775. progp->service_provider_name, progp->service_name, progp->txtlang,
  776. progp->txttype, progp->txtmagazine, progp->txtpage);
  777. vbi->ttpid = progp->ttpid;
  778. ttpidfound:
  779. rawbuf = malloc(rawbuf_size = 8192);
  780. if (!rawbuf)
  781. goto outerr;
  782. rawptr = 0;
  783. #if 0
  784. close(vbi->fd);
  785. if ((vbi->fd = open(vbi_name, O_RDWR)) == -1) {
  786. error("cannot open demux device %s", vbi_name);
  787. return -1;
  788. }
  789. #endif
  790. memset(&filterpar, 0, sizeof(filterpar));
  791. filterpar.pid = vbi->ttpid;
  792. filterpar.input = DMX_IN_FRONTEND;
  793. filterpar.output = DMX_OUT_TAP;
  794. filterpar.pes_type = DMX_PES_OTHER;
  795. filterpar.flags = DMX_IMMEDIATE_START;
  796. if (ioctl(vbi->fd, DMX_SET_PES_FILTER, &filterpar) < 0) {
  797. error("ioctl: DMX_SET_PES_FILTER %s (%u)", strerror(errno), errno);
  798. goto outerr;
  799. }
  800. return 0;
  801. outerr:
  802. close(vbi->fd);
  803. vbi->fd = -1;
  804. return -1;
  805. }
  806. struct vbi *open_null_vbi(struct cache *ca)
  807. {
  808. static int inited = 0;
  809. struct vbi *vbi;
  810. if (not inited)
  811. lang_init();
  812. inited = 1;
  813. vbi = malloc(sizeof(*vbi));
  814. if (!vbi)
  815. {
  816. error("out of memory");
  817. goto fail1;
  818. }
  819. vbi->fd = open("/dev/null", O_RDONLY);
  820. if (vbi->fd == -1)
  821. {
  822. error("cannot open null device");
  823. goto fail2;
  824. }
  825. vbi->ttpid = -1;
  826. out_of_sync(vbi);
  827. vbi->ppage = vbi->rpage;
  828. fdset_add_fd(fds, vbi->fd, vbi_handler, vbi);
  829. return vbi;
  830. fail3:
  831. close(vbi->fd);
  832. fail2:
  833. free(vbi);
  834. fail1:
  835. return 0;
  836. }
  837. void send_errmsg(struct vbi *vbi, char *errmsg, ...)
  838. {
  839. va_list args;
  840. if (errmsg == NULL || *errmsg == '\0')
  841. return;
  842. va_start(args, errmsg);
  843. char *buff = NULL;
  844. if (vasprintf(&buff, errmsg, args) < 0)
  845. buff = NULL;
  846. va_end(args);
  847. if(buff == NULL)
  848. out_of_mem(-1);
  849. vbi_send(vbi, EV_ERR, 0, 0, 0, buff);
  850. }