comparison recpt1/recpt1.c @ 96:52f8e081763d

add an option to specify the necessary service IDs. patch by Naoya OYAMA <naoya.oyama@gmail.com>, based on the code of tssplitter_lite by querulous.
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Wed, 10 Feb 2010 14:33:32 +0900
parents 2b55985bbb4c
children 4d201756c593
comparison
equal deleted inserted replaced
95:a201531113ca 96:52f8e081763d
28 #include "version.h" 28 #include "version.h"
29 #include "mkpath.h" 29 #include "mkpath.h"
30 30
31 #include <sys/ipc.h> 31 #include <sys/ipc.h>
32 #include <sys/msg.h> 32 #include <sys/msg.h>
33 #include "pt1_dev.h"
34 #include "tssplitter_lite.h"
33 35
34 /* maximum write length at once */ 36 /* maximum write length at once */
35 #define SIZE_CHANK 1316 37 #define SIZE_CHANK 1316
36 38
37 /* ipc message size */ 39 /* ipc message size */
58 pthread_t signal_thread; 60 pthread_t signal_thread;
59 int recsec; 61 int recsec;
60 time_t start_time; 62 time_t start_time;
61 boolean indefinite; 63 boolean indefinite;
62 int msqid; 64 int msqid;
65 splitter *splitter;
63 } thread_data; 66 } thread_data;
64 67
65 typedef struct msgbuf { 68 typedef struct msgbuf {
66 long mtype; 69 long mtype;
67 char mtext[MSGSZ]; 70 char mtext[MSGSZ];
286 reader_func(void *p) 289 reader_func(void *p)
287 { 290 {
288 thread_data *data = (thread_data *)p; 291 thread_data *data = (thread_data *)p;
289 QUEUE_T *p_queue = data->queue; 292 QUEUE_T *p_queue = data->queue;
290 decoder *dec = data->decoder; 293 decoder *dec = data->decoder;
294 splitter *splitter = data->splitter;
291 int wfd = data->wfd; 295 int wfd = data->wfd;
292 boolean use_b25 = dec ? TRUE : FALSE; 296 boolean use_b25 = dec ? TRUE : FALSE;
293 boolean use_udp = data->sock_data ? TRUE : FALSE; 297 boolean use_udp = data->sock_data ? TRUE : FALSE;
294 boolean fileless = FALSE; 298 boolean fileless = FALSE;
299 boolean use_splitter = splitter ? TRUE : FALSE;
295 int sfd = -1; 300 int sfd = -1;
296 pthread_t signal_thread = data->signal_thread; 301 pthread_t signal_thread = data->signal_thread;
297 struct sockaddr_in *addr = NULL; 302 struct sockaddr_in *addr = NULL;
298 BUFSZ *qbuf; 303 BUFSZ *qbuf;
304 BUFSZ splitbuf;
299 ARIB_STD_B25_BUFFER sbuf, dbuf, buf; 305 ARIB_STD_B25_BUFFER sbuf, dbuf, buf;
300 int code; 306 int code;
307 int split_select_finish = TSS_ERROR;
301 308
302 if(wfd == -1) 309 if(wfd == -1)
303 fileless = TRUE; 310 fileless = TRUE;
304 311
305 if(use_udp) { 312 if(use_udp) {
318 325
319 sbuf.data = qbuf->buffer; 326 sbuf.data = qbuf->buffer;
320 sbuf.size = qbuf->size; 327 sbuf.size = qbuf->size;
321 328
322 buf = sbuf; /* default */ 329 buf = sbuf; /* default */
330
331 if ( use_splitter )
332 {
333 /* $BJ,N%BP>](BPID$B$NCj=P(B */
334 if ( split_select_finish != TSS_SUCCESS )
335 {
336 split_select_finish = split_select(splitter, &sbuf);
337 if ( split_select_finish == TSS_NULL )
338 {
339 /* malloc$B%(%i!<H/@8(B */
340 use_splitter = FALSE;
341 }
342 else if ( split_select_finish != TSS_SUCCESS )
343 {
344 /* $BJ,N%BP>](BPID$B$,40A4$KCj=P$G$-$k$^$G=PNO$7$J$$(B
345 * 1$BICDxEYM>M5$r8+$k$H$$$$$+$b(B
346 */
347 free(qbuf);
348 qbuf = NULL;
349 continue;
350 }
351 }
352 /* $BJ,N%BP>]0J30$r$U$k$$Mn$H$9(B */
353 code = split_ts(splitter, &sbuf, &splitbuf);
354 if ( code != TSS_SUCCESS )
355 {
356 free(qbuf);
357 qbuf = NULL;
358 continue;
359 }
360 /* $BJ,N%7k2L$,%<%m%P%$%H$G$"$k>l9g$K$O(Bb25$B$K2s$5$J$$(B */
361 if ( splitbuf.size == 0 )
362 {
363 free(qbuf);
364 qbuf = NULL;
365 continue;
366 }
367 sbuf.data = splitbuf.buffer;
368 sbuf.size = splitbuf.size;
369 buf = sbuf;
370 }
323 371
324 if(use_b25) { 372 if(use_b25) {
325 code = b25_decode(dec, &sbuf, &dbuf); 373 code = b25_decode(dec, &sbuf, &dbuf);
326 if(code < 0) { 374 if(code < 0) {
327 fprintf(stderr, "b25_decode failed. fall back to encrypted recording.\n"); 375 fprintf(stderr, "b25_decode failed. fall back to encrypted recording.\n");
365 size_remain -= wc; 413 size_remain -= wc;
366 offset += wc; 414 offset += wc;
367 } 415 }
368 } 416 }
369 417
370 free(qbuf); 418 if ( qbuf != NULL ) {
419 free(qbuf);
420 qbuf = NULL;
421 }
371 422
372 /* normal exit */ 423 /* normal exit */
373 if((f_exit && !p_queue->num_used) || file_err) { 424 if((f_exit && !p_queue->num_used) || file_err) {
374 425
375 buf = sbuf; /* default */ 426 buf = sbuf; /* default */
427
428 if ( use_splitter )
429 {
430 /* $BJ,N%BP>]0J30$r$U$k$$Mn$H$9(B */
431 code = split_ts(splitter, &sbuf, &splitbuf);
432 if ( code != TSS_SUCCESS )
433 {
434 break;
435 }
436 /* $BJ,N%7k2L$,%<%m%P%$%H$G$"$k>l9g$K$O(Bb25$B$K2s$5$J$$(B */
437 if ( splitbuf.size == 0 )
438 {
439 break;
440 }
441 sbuf.data = splitbuf.buffer;
442 sbuf.size = splitbuf.size;
443 buf = sbuf;
444 }
376 445
377 if(use_b25) { 446 if(use_b25) {
378 code = b25_finish(dec, &sbuf, &dbuf); 447 code = b25_finish(dec, &sbuf, &dbuf);
379 if(code < 0) 448 if(code < 0)
380 fprintf(stderr, "b25_finish failed\n"); 449 fprintf(stderr, "b25_finish failed\n");
414 483
415 void 484 void
416 show_usage(char *cmd) 485 show_usage(char *cmd)
417 { 486 {
418 #ifdef HAVE_LIBARIB25 487 #ifdef HAVE_LIBARIB25
419 fprintf(stderr, "Usage: \n%s [--b25 [--round N] [--strip] [--EMM]] [--udp [--addr hostname --port portnumber]] [--device devicefile] [--lnb voltage] channel rectime destfile\n", cmd); 488 fprintf(stderr, "Usage: \n%s [--b25 [--round N] [--strip] [--EMM]] [--udp [--addr hostname --port portnumber]] [--device devicefile] [--lnb voltage] [--split SID1,SID2] channel rectime destfile\n", cmd);
420 #else 489 #else
421 fprintf(stderr, "Usage: \n%s [--strip] [--EMM]] [--udp [--addr hostname --port portnumber]] [--device devicefile] [--lnb voltage] channel rectime destfile\n", cmd); 490 fprintf(stderr, "Usage: \n%s [--strip] [--EMM]] [--udp [--addr hostname --port portnumber]] [--device devicefile] [--lnb voltage] [--split SID1,SID2] channel rectime destfile\n", cmd);
422 #endif 491 #endif
423 fprintf(stderr, "\n"); 492 fprintf(stderr, "\n");
424 fprintf(stderr, "Remarks:\n"); 493 fprintf(stderr, "Remarks:\n");
425 fprintf(stderr, "if rectime is '-', records indefinitely.\n"); 494 fprintf(stderr, "if rectime is '-', records indefinitely.\n");
426 fprintf(stderr, "if destfile is '-', stdout is used for output.\n"); 495 fprintf(stderr, "if destfile is '-', stdout is used for output.\n");
439 fprintf(stderr, "--udp: Turn on udp broadcasting\n"); 508 fprintf(stderr, "--udp: Turn on udp broadcasting\n");
440 fprintf(stderr, " --addr hostname: Hostname or address to connect\n"); 509 fprintf(stderr, " --addr hostname: Hostname or address to connect\n");
441 fprintf(stderr, " --port portnumber: Port number to connect\n"); 510 fprintf(stderr, " --port portnumber: Port number to connect\n");
442 fprintf(stderr, "--device devicefile: Specify devicefile to use\n"); 511 fprintf(stderr, "--device devicefile: Specify devicefile to use\n");
443 fprintf(stderr, "--lnb voltage: Specify LNB voltage (0, 11, 15)\n"); 512 fprintf(stderr, "--lnb voltage: Specify LNB voltage (0, 11, 15)\n");
513 fprintf(stderr, "--split SID1,SID2...,SIDN: Specify SID number in CSV format(100,101,102,...)\n");
444 fprintf(stderr, "--help: Show this help\n"); 514 fprintf(stderr, "--help: Show this help\n");
445 fprintf(stderr, "--version: Show version\n"); 515 fprintf(stderr, "--version: Show version\n");
446 fprintf(stderr, "--list: Show channel list\n"); 516 fprintf(stderr, "--list: Show channel list\n");
447 } 517 }
448 518
793 pthread_t reader_thread; 863 pthread_t reader_thread;
794 pthread_t ipc_thread; 864 pthread_t ipc_thread;
795 QUEUE_T *p_queue = create_queue(MAX_QUEUE); 865 QUEUE_T *p_queue = create_queue(MAX_QUEUE);
796 BUFSZ *bufptr; 866 BUFSZ *bufptr;
797 decoder *dec = NULL; 867 decoder *dec = NULL;
868 splitter *splitter = NULL;
798 static thread_data tdata; 869 static thread_data tdata;
799 decoder_options dopt = { 870 decoder_options dopt = {
800 4, /* round */ 871 4, /* round */
801 0, /* strip */ 872 0, /* strip */
802 0 /* emm */ 873 0 /* emm */
822 { "port", 1, NULL, 'p'}, 893 { "port", 1, NULL, 'p'},
823 { "device", 1, NULL, 'd'}, 894 { "device", 1, NULL, 'd'},
824 { "help", 0, NULL, 'h'}, 895 { "help", 0, NULL, 'h'},
825 { "version", 0, NULL, 'v'}, 896 { "version", 0, NULL, 'v'},
826 { "list", 0, NULL, 'l'}, 897 { "list", 0, NULL, 'l'},
898 { "split", 1, NULL, 'i'},
827 {0, 0, NULL, 0} /* terminate */ 899 {0, 0, NULL, 0} /* terminate */
828 }; 900 };
829 901
830 boolean use_b25 = FALSE; 902 boolean use_b25 = FALSE;
831 boolean use_udp = FALSE; 903 boolean use_udp = FALSE;
832 boolean fileless = FALSE; 904 boolean fileless = FALSE;
833 boolean use_stdout = FALSE; 905 boolean use_stdout = FALSE;
906 boolean use_splitter = FALSE;
834 char *host_to = NULL; 907 char *host_to = NULL;
835 int port_to = 1234; 908 int port_to = 1234;
836 sock_data *sockdata = NULL; 909 sock_data *sockdata = NULL;
837 char *device = NULL; 910 char *device = NULL;
838 int val; 911 int val;
839 char *voltage[] = {"0V", "11V", "15V"}; 912 char *voltage[] = {"0V", "11V", "15V"};
913 char *sid_list = NULL;
840 914
841 while((result = getopt_long(argc, argv, "br:smn:ua:p:d:hvl", 915 while((result = getopt_long(argc, argv, "br:smn:ua:p:d:hvl",
842 long_options, &option_index)) != -1) { 916 long_options, &option_index)) != -1) {
843 switch(result) { 917 switch(result) {
844 case 'b': 918 case 'b':
908 break; 982 break;
909 case 'd': 983 case 'd':
910 device = optarg; 984 device = optarg;
911 fprintf(stderr, "using device: %s\n", device); 985 fprintf(stderr, "using device: %s\n", device);
912 break; 986 break;
987 case 'i':
988 use_splitter = TRUE;
989 sid_list = optarg;
990 break;
913 } 991 }
914 } 992 }
915 993
916 if(argc - optind < 3) { 994 if(argc - optind < 3) {
917 if(argc - optind == 2 && use_udp) { 995 if(argc - optind == 2 && use_udp) {
966 dec = b25_startup(&dopt); 1044 dec = b25_startup(&dopt);
967 if(!dec) { 1045 if(!dec) {
968 fprintf(stderr, "Cannot start b25 decoder\n"); 1046 fprintf(stderr, "Cannot start b25 decoder\n");
969 fprintf(stderr, "Fall back to encrypted recording\n"); 1047 fprintf(stderr, "Fall back to encrypted recording\n");
970 use_b25 = 0; 1048 use_b25 = 0;
1049 }
1050 }
1051 /* initialize splitter */
1052 if(use_splitter)
1053 {
1054 splitter = split_startup(sid_list);
1055 if ( splitter->sid_list == NULL )
1056 {
1057 fprintf(stderr, "Cannot start TS splitter\n");
1058 return(1);
971 } 1059 }
972 } 1060 }
973 1061
974 /* initialize udp connection */ 1062 /* initialize udp connection */
975 if(use_udp) { 1063 if(use_udp) {
1001 } 1089 }
1002 1090
1003 /* prepare thread data */ 1091 /* prepare thread data */
1004 tdata.queue = p_queue; 1092 tdata.queue = p_queue;
1005 tdata.decoder = dec; 1093 tdata.decoder = dec;
1094 tdata.splitter = splitter;
1006 tdata.sock_data = sockdata; 1095 tdata.sock_data = sockdata;
1007 1096
1008 /* spawn signal handler thread */ 1097 /* spawn signal handler thread */
1009 init_signal_handlers(&signal_thread, &tdata); 1098 init_signal_handlers(&signal_thread, &tdata);
1010 1099
1107 1196
1108 /* release decoder */ 1197 /* release decoder */
1109 if(use_b25) { 1198 if(use_b25) {
1110 b25_shutdown(dec); 1199 b25_shutdown(dec);
1111 } 1200 }
1201 if(use_splitter) {
1202 split_shutdown(splitter);
1203 }
1112 1204
1113 return 0; 1205 return 0;
1114 } 1206 }