Mercurial > pt1
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 } |