Пример #1
0
bool XMLTVParser::parseFile(
    QString filename, QList<ChanInfo> *chanlist,
    QMap<QString, QList<ProgInfo> > *proglist)
{
    QDomDocument doc;
    QFile f;

    if (!dash_open(f, filename, QIODevice::ReadOnly))
    {
        VERBOSE(VB_IMPORTANT, QString("Error unable to open '%1' for reading.")
                .arg(filename));
        return false;
    }

    QString errorMsg = "unknown";
    int errorLine = 0;
    int errorColumn = 0;

    if (!doc.setContent(&f, &errorMsg, &errorLine, &errorColumn))
    {
        VERBOSE(VB_IMPORTANT, QString("Error in %1:%2: %3")
            .arg(errorLine).arg(errorColumn).arg(errorMsg));

        f.close();
        return true;
    }

    f.close();

    // now we calculate the localTimezoneOffset, so that we can fix
    // the programdata if needed
    QString config_offset = gCoreContext->GetSetting("TimeOffset", "None");
    // we disable this feature by setting it invalid (> 840min = 14hr)
    int localTimezoneOffset = 841;

    if (config_offset == "Auto")
    {
        // we mark auto with the -ve of the disable magic number
        localTimezoneOffset = -841;
    }
    else if (config_offset != "None")
    {
        localTimezoneOffset = TimezoneToInt(config_offset);
        if (abs(localTimezoneOffset) > 840)
        {
            VERBOSE(VB_XMLTV, QString("Ignoring invalid TimeOffset %1")
                .arg(config_offset));
            localTimezoneOffset = 841;
        }
    }

    QDomElement docElem = doc.documentElement();

    QUrl baseUrl(docElem.attribute("source-data-url", ""));

    QUrl sourceUrl(docElem.attribute("source-info-url", ""));
    if (sourceUrl.toString() == "http://labs.zap2it.com/")
    {
        VERBOSE(VB_IMPORTANT, "Don't use tv_grab_na_dd, use the"
            "internal datadirect grabber.");
        exit(GENERIC_EXIT_SETUP_ERROR);
    }

    QString aggregatedTitle;
    QString aggregatedDesc;
    QString groupingTitle;
    QString groupingDesc;

    QDomNode n = docElem.firstChild();
    while (!n.isNull())
    {
        QDomElement e = n.toElement();
        if (!e.isNull())
        {
            if (e.tagName() == "channel")
            {
                ChanInfo *chinfo = parseChannel(e, baseUrl);
                chanlist->push_back(*chinfo);
                delete chinfo;
            }
            else if (e.tagName() == "programme")
            {
                ProgInfo *pginfo = parseProgram(e, localTimezoneOffset);

                if (pginfo->startts == pginfo->endts)
                {
                    /* Not a real program : just a grouping marker */
                    if (!pginfo->title.isEmpty())
                        groupingTitle = pginfo->title + " : ";

                    if (!pginfo->description.isEmpty())
                        groupingDesc = pginfo->description + " : ";
                }
                else
                {
                    if (pginfo->clumpidx.isEmpty())
                    {
                        if (!groupingTitle.isEmpty())
                        {
                            pginfo->title.prepend(groupingTitle);
                            groupingTitle.clear();
                        }

                        if (!groupingDesc.isEmpty())
                        {
                            pginfo->description.prepend(groupingDesc);
                            groupingDesc.clear();
                        }

                        (*proglist)[pginfo->channel].push_back(*pginfo);
                    }
                    else
                    {
                        /* append all titles/descriptions from one clump */
                        if (pginfo->clumpidx.toInt() == 0)
                        {
                            aggregatedTitle.clear();
                            aggregatedDesc.clear();
                        }

                        if (!pginfo->title.isEmpty())
                        {
                            if (!aggregatedTitle.isEmpty())
                                aggregatedTitle.append(" | ");
                            aggregatedTitle.append(pginfo->title);
                        }

                        if (!pginfo->description.isEmpty())
                        {
                            if (!aggregatedDesc.isEmpty())
                                aggregatedDesc.append(" | ");
                            aggregatedDesc.append(pginfo->description);
                        }
                        if (pginfo->clumpidx.toInt() ==
                            pginfo->clumpmax.toInt() - 1)
                        {
                            pginfo->title = aggregatedTitle;
                            pginfo->description = aggregatedDesc;
                            (*proglist)[pginfo->channel].push_back(*pginfo);
                        }
                    }
                }
                delete pginfo;
            }
        }
        n = n.nextSibling();
    }

    return true;
}
Пример #2
0
bool XMLTVParser::parseFile(
    QString filename, ChannelInfoList *chanlist,
    QMap<QString, QList<ProgInfo> > *proglist)
{
    QDomDocument doc;
    QFile f;

    if (!dash_open(f, filename, QIODevice::ReadOnly))
    {
        LOG(VB_GENERAL, LOG_ERR,
            QString("Error unable to open '%1' for reading.") .arg(filename));
        return false;
    }

    QString errorMsg = "unknown";
    int errorLine = 0;
    int errorColumn = 0;

    if (!doc.setContent(&f, &errorMsg, &errorLine, &errorColumn))
    {
        LOG(VB_GENERAL, LOG_ERR, QString("Error in %1:%2: %3")
            .arg(errorLine).arg(errorColumn).arg(errorMsg));

        f.close();
        return true;
    }

    f.close();

    QDomElement docElem = doc.documentElement();

    QUrl baseUrl(docElem.attribute("source-data-url", ""));
    //QUrl sourceUrl(docElem.attribute("source-info-url", ""));

    QString aggregatedTitle;
    QString aggregatedDesc;

    QDomNode n = docElem.firstChild();
    while (!n.isNull())
    {
        QDomElement e = n.toElement();
        if (!e.isNull())
        {
            if (e.tagName() == "channel")
            {
                ChannelInfo *chinfo = parseChannel(e, baseUrl);
                if (!chinfo->xmltvid.isEmpty())
                    chanlist->push_back(*chinfo);
                delete chinfo;
            }
            else if (e.tagName() == "programme")
            {
                ProgInfo *pginfo = parseProgram(e);

                if (pginfo->startts == pginfo->endts)
                {
                    LOG(VB_GENERAL, LOG_WARNING, QString("Invalid programme (%1), "
                                                        "identical start and end "
                                                        "times, skipping")
                                                        .arg(pginfo->title));
                }
                else
                {
                    if (pginfo->clumpidx.isEmpty())
                        (*proglist)[pginfo->channel].push_back(*pginfo);
                    else
                    {
                        /* append all titles/descriptions from one clump */
                        if (pginfo->clumpidx.toInt() == 0)
                        {
                            aggregatedTitle.clear();
                            aggregatedDesc.clear();
                        }

                        if (!pginfo->title.isEmpty())
                        {
                            if (!aggregatedTitle.isEmpty())
                                aggregatedTitle.append(" | ");
                            aggregatedTitle.append(pginfo->title);
                        }

                        if (!pginfo->description.isEmpty())
                        {
                            if (!aggregatedDesc.isEmpty())
                                aggregatedDesc.append(" | ");
                            aggregatedDesc.append(pginfo->description);
                        }
                        if (pginfo->clumpidx.toInt() ==
                            pginfo->clumpmax.toInt() - 1)
                        {
                            pginfo->title = aggregatedTitle;
                            pginfo->description = aggregatedDesc;
                            (*proglist)[pginfo->channel].push_back(*pginfo);
                        }
                    }
                }
                delete pginfo;
            }
        }
        n = n.nextSibling();
    }

    return true;
}
Пример #3
0
/**
 * オプションの解析
 */
Args
parseOption(int argc, char *argv[])
{
	Args args = {
#ifdef B25
		false,
		4,
		false,
		false,
		false,
#endif /* defined(B25) */
#ifdef HDUS
		false,
		false,
#endif /* defined(HDUS) */
		NULL,
		false,
#ifdef UDP
		"",
		UDP_PORT,
#endif /* defined(UDP) */
#ifdef HTTP
		false,
		HTTP_PORT,
#endif /* defined(HTTP) */
#ifdef TSSL
		false,
		NULL,
#endif /* defined(TSSL) */
		false,
		TUNER_FRIIO_WHITE,
		BAND_UHF,
		0,
		false,
		0,
		NULL,
	};

	while (1) {
		int option_index = 0;
		static option long_options[] = {
#ifdef B25
			{ "b25",      0, NULL, 'b' },
			{ "B25",      0, NULL, 'b' },
			{ "round",    1, NULL, 'r' },
			{ "strip",    0, NULL, 's' },
			{ "EMM",      0, NULL, 'm' },
			{ "emm",      0, NULL, 'm' },
			{ "sync",     0, NULL, 'S' },
#endif /* defined(B25) */
#ifdef HDUS
			{ "hdus",     0, NULL, 'h' },
			{ "hdp",      0, NULL, 'd' },
#endif /* defined(HDUS) */
			{ "lockfile", 1, NULL, 'l' },
			{ "lnb",      0, NULL, 'n' },
#ifdef UDP
			{ "udp",      1, NULL, 'u' },
			{ "port",     1, NULL, 'p' },
#endif /* defined(UDP) */
#ifdef HTTP
			{ "http",     1, NULL, 'H' },
#endif /* defined(HTTP) */
#ifdef TSSL
			{ "sid",      1, NULL, 'i' },
#endif /* defined(TSSL) */
			{ 0,          0, NULL, 0   }
		};
		
		int r = getopt_long(argc, argv,
#ifdef B25
		                    "br:smS"
#endif /* defined(B25) */
#ifdef UDP
		                    "u:p:"
#endif /* defined(B25) */
#ifdef HTTP
		                    "H:"
#endif /* defined(HTTP) */
#ifdef TSSL
		                    "i:"
#endif /* defined(TSSL) */
		                    "l:",
		                    long_options, &option_index);
		if (r < 0) {
			break;
		}
		
		switch (r) {
#ifdef B25
			case 'b':
				args.b25 = true;
				break;
			case 'r':
				args.round = atoi(optarg);
				break;
			case 's':
				args.strip = true;
				break;
			case 'm':
				args.emm = true;
				break;
			case 'S':
				args.sync = true;
				break;
#endif /* defined(B25) */
#ifdef HDUS
			case 'h':
				args.use_hdus = true;
				break;
			case 'd':
				args.use_hdp = true;
				break;
#endif /* defined(HDUS) */
			case 'l':
				args.lockfile = optarg;
				break;
			case 'n':
				args.lnb = true;
				break;
#ifdef UDP
			case 'u':
				args.ip = optarg;
				break;
			case 'p':
				args.port = atoi(optarg);
				break;
#endif /* defined(UDP) */
#ifdef HTTP
			case 'H':
				args.http_mode = true;
				args.http_port = atoi(optarg);
				args.forever = true;
				return args;
				break;
#endif /* defined(HTTP) */
#ifdef TSSL
			case 'i':
				args.splitter = true;
				args.sid_list = optarg;
				break;
#endif /* defined(TSSL) */
			default:
				break;
		}
	}
	
	if (argc - optind != 3) {
		usage(argv);
	}
	
	parseChannel(&args, argv[optind++]);
	char *recsecstr = argv[optind++];
	if (strcmp("-", recsecstr) == 0) {
		args.forever = true;
	}
	args.recsec    = atoi(recsecstr);
	args.destfile = argv[optind++];
	if (strcmp("-", args.destfile) == 0) {
		args.stdout = true;
	}
	
	return args;
}
Пример #4
0
/** main */
int
main(int argc, char *argv[])
{
	Args args = parseOption(argc, argv);
	// 正常終了時戻り値
	int result = 0;
	boost::scoped_ptr<Recordable> tuner(NULL);
	timeval tv_start;
#ifdef UDP
	Udp udp;
#endif /* defined(UDP) */
#ifdef HTTP
	int dest = 1; // stdout
	int connected_socket = 0;
	int listening_socket = 0;
#endif /* defined(HTTP) */
	
	// 引数確認
	if (!args.forever && args.recsec <= 0) {
		std::cerr << "recsec must be (recsec > 0)." << std::endl;
		exit(1);
	}
	
	// 録画時間の基準開始時間
	time_t time_start = time(NULL);
	
	// ログ出力先設定
	std::ostream& log = args.stdout ? std::cerr : std::cout;

#ifdef HTTP
	if( !args.http_mode ){
		// 出力先ファイルオープン
		if(!args.stdout) {
			dest = open(args.destfile, (O_RDWR | O_CREAT | O_TRUNC), 0666);
			if (0 > dest) {
				std::cerr << "can't open file '" << args.destfile << "' to write." << std::endl;
				exit(1);
			}
		}
	}else{
		struct sockaddr_in	sin;
		int					sock_optval = 1;
		int					ret;

		fprintf(stderr, "run as a daemon..\n");
		if(daemon(1,1)){
			perror("failed to start");
			exit(1);
		}

		listening_socket = socket(AF_INET, SOCK_STREAM, 0);
		if ( listening_socket == -1 ){
			perror("socket");
			exit(1);
		}

		if ( setsockopt(listening_socket, SOL_SOCKET, SO_REUSEADDR, &sock_optval, sizeof(sock_optval)) == -1 ){
			perror("setsockopt");
			exit(1);
		}

		sin.sin_family = AF_INET;
		sin.sin_port = htons(args.http_port);
		sin.sin_addr.s_addr = htonl(INADDR_ANY);

		if ( bind(listening_socket, (struct sockaddr *)&sin, sizeof(sin)) < 0 ){
			perror("bind");
			exit(1);
		}

		ret = listen(listening_socket, SOMAXCONN);
		if ( ret == -1 ){
			perror("listen");
			exit(1);
		}
		fprintf(stderr,"listening at port %d\n", args.http_port);
	}

	while(1){
		if ( args.http_mode ) {
			struct sockaddr_in	peer_sin;
			int					read_size;
			unsigned int		len;
			char				buffer[256];
			char				s0[256],s1[256],s2[256];
			char				delim[] = "/";
			char				*channel;
			char				*sidflg;

			len = sizeof(peer_sin);
			connected_socket = accept(listening_socket, (struct sockaddr *)&peer_sin, &len);
			if ( connected_socket == -1 ) {
				perror("accept");
				exit(1);
			}

			int error;
			char hbuf[NI_MAXHOST], nhbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
			error = getnameinfo((struct sockaddr *)&peer_sin, sizeof(peer_sin), hbuf, sizeof(hbuf), NULL, 0, 0);
			if (error) {
				fprintf(stderr, "getnameinfo(): %s\n", gai_strerror(error));
				exit(1);
			}
			error = getnameinfo((struct sockaddr *)&peer_sin, sizeof(peer_sin), nhbuf, sizeof(nhbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV);
			if (error) {
				fprintf(stderr, "getnameinfo(): %s\n", gai_strerror(error));
				exit(1);
			}
			fprintf(stderr,"connect from: %s [%s] port %s\n", hbuf, nhbuf, sbuf);

			read_size = read_line(connected_socket, buffer);
			fprintf(stderr, "request command is %s\n", buffer);
			// ex:GET /C8/333 HTTP/1.1
			sscanf(buffer, "%s%s%s", s0, s1, s2);
			channel = strtok(s1, delim);
			if (channel != NULL) {
				fprintf(stderr, "Channel: %s\n", channel);
				parseChannel(&args, channel);
				sidflg = strtok(NULL, delim);
				if (sidflg != NULL) {
					fprintf(stderr, "SID: %s\n", sidflg);
#ifdef TSSL
					args.splitter = true;
					args.sid_list = sidflg;
				} else {
					args.splitter = false;
					args.sid_list = NULL;
#endif /* defined(TSSL) */
				}
			}
			char header[] =  "HTTP/1.1 200 OK\r\nContent-Type: application/octet-stream\r\nCache-Control: no-cache\r\n\r\n";
			write(connected_socket, header, strlen(header));
			//set write target to http
			dest = connected_socket;
		}
#endif /* defined(HTTP) */

#ifdef B25
	// B25初期化
	B25Decoder b25dec;
	if (args.b25) {
		try {
			b25dec.setRound(args.round);
			b25dec.setStrip(args.strip);
			b25dec.setEmmProcess(args.emm);
			b25dec.open();
			log << "B25Decoder initialized." << std::endl;
		} catch (b25_error& e) {
			std::cerr << e.what() << std::endl;
			
#ifdef HTTP
			if (!args.http_mode) {
#endif /* defined(HTTP) */
			// エラー時b25を行わず処理続行。終了ステータス1
			std::cerr << "disable b25 decoding." << std::endl;
			args.b25 = false;
			result = 1;
#ifdef HTTP
			}
#endif /* defined(HTTP) */
		}
	}
#endif /* defined(B25) */

#ifdef UDP
	// UDP初期化
	if( ! args.ip.empty() ){
		try{
			udp.setLog(&log);
			udp.init( args.ip, args.port );
		}
		catch( const char* e ){
			log << e << std::endl;
			log << "disable UDP." << std::endl;
		}
	}
#endif /* defined(UDP) */

#ifdef TSSL
	/* initialize splitter */
	splitbuf_t splitbuf;
	splitbuf.size = 0;
	splitter *splitter = NULL;
	int split_select_finish = TSS_ERROR;
	int code;
	if(args.splitter) {
		splitter = split_startup(args.sid_list);
		if(splitter->sid_list == NULL) {
			fprintf(stderr, "Cannot start TS splitter\n");
			return 1;
		}
	}
#endif /* defined(TSSL) */

	// Tuner取得
	tuner.reset(createRecordable(args.type));
#ifdef HDUS
	if( args.type == TUNER_HDUS ) log << "Tuner type is HDUS." << std::endl;
	else if( args.type == TUNER_HDP ) log << "Tuner type is HDP." << std::endl;
#endif /* defined(HDUS) */
	// ログ出力先設定
	tuner->setLog(&log);
	// ロックファイル設定
	if (args.lockfile != NULL) {
		tuner->setDetectLockFile(args.lockfile);
	}
	
	// Tuner初期化
	int retryCount = ERROR_RETRY_MAX;
	while (0 < retryCount) {
		try {
			// チューナopen
			bool r = tuner->open(args.lnb);
			if (!r) {
				std::cerr << "can't open tuner." << std::endl;
				exit(1);
			}
			
			// チャンネル設定
			tuner->setChannel(args.band, args.channel);
			
			// 開始時SignalLevel出力
			float lev_before = 0.0;
			int lev_retry_count = SIGNALLEVEL_RETRY_MAX;
			while (lev_before < SIGNALLEVEL_RETRY_THRESHOLD && 0 < lev_retry_count) {
				lev_before = tuner->getSignalLevel();
				log << "Signal level: " << lev_before << std::endl;
				
				lev_retry_count--;
				usleep(SIGNALLEVEL_RETRY_INTERVAL * 1000);
			}
		} catch (usb_error& e) {
			// リトライ処理
			retryCount--;
			std::cerr << e.what();
			if (retryCount <= 0) {
				std::cerr << " abort." << std::endl;
				exit(1);
			}
			std::cerr << " retry." << std::endl;
			
			tuner->close();
			usleep(ERROR_RETRY_INTERVAL * 1000);
			continue;
		}
		break;
	}
	
#ifndef HTTP
	// 出力先ファイルオープン
	FILE *dest = stdout;
	if (!args.stdout) {
		dest = fopen(args.destfile, "w");
		if (NULL == dest) {
			std::cerr << "can't open file '" << args.destfile << "' to write." << std::endl;
			exit(1);
		}
	}
#endif /* !defined(HTTP) */
	
	// 出力開始/時間計測
	log << "Output ts file." << std::endl;
	if (gettimeofday(&tv_start, NULL) < 0) {
		std::cerr << "gettimeofday failed." << std::endl;
		exit(1);
	}
	
	// SIGINT/SIGTERMキャッチ
	struct sigaction sa;
	memset(&sa, 0, sizeof(struct sigaction));
	sa.sa_handler = sighandler;
	sa.sa_flags = SA_RESTART;
	struct sigaction saDefault;
	memset(&saDefault, 0, sizeof(struct sigaction));
	saDefault.sa_handler = SIG_DFL;
	sigaction(SIGINT,  &sa, NULL);
	sigaction(SIGTERM, &sa, NULL);
	sigaction(SIGPIPE, &sa, NULL);
	
	uint8_t		*buf = NULL;
	int			rlen;
	
	// 受信スレッド起動
	tuner->startStream();
	// データ読み出し
	uint32_t urb_error_cnt = 0;
	while (!caughtSignal && (args.forever || time(NULL) <= time_start + args.recsec)) {
		try {
			rlen = tuner->getStream((const uint8_t **)&buf, 200);
			if (0 == rlen) {
				continue;
			}
			
#ifdef B25
			// B25を経由させる。
			if (args.b25) {
				static int f_b25_sync = 0;
				try {
					uint8_t *b25buf;
					b25dec.put(buf, rlen);
					rlen = b25dec.get((const uint8_t **)&b25buf);
					if (0 == rlen) {
						continue;
					}
					f_b25_sync = 1;
					buf = b25buf;
				} catch (b25_error& e) {
					if( f_b25_sync == 0 && args.sync ){
						log << "Wait for B25 sync" << std::endl;
						continue;
					}
					log << "B25 Error: " << e.what() << std::endl;
					log << "Continue recording without B25." << std::endl;
#ifdef HTTP
					if (!args.http_mode) {
#endif /* defined(HTTP) */
					// b25停止、戻り値エラー
					args.b25 = false;
					result = 1;
#ifdef HTTP
					}
#endif /* defined(HTTP) */
				}
			}
#endif /* defined(B25) */

#ifdef TSSL
			if (args.splitter) {
				splitbuf.size = 0;
				while (rlen) {
					/* 分離対象PIDの抽出 */
					if (split_select_finish != TSS_SUCCESS) {
						split_select_finish = split_select(splitter, buf, rlen);
						if (split_select_finish == TSS_NULL) {
							/* mallocエラー発生 */
							log << "split_select malloc failed" << std::endl;
							args.splitter = false;
							result = 1;
							goto fin;
						} else if (split_select_finish != TSS_SUCCESS) {
							// 分離対象PIDが完全に抽出できるまで出力しない
							// 1秒程度余裕を見るといいかも
							time_t cur_time;
							time(&cur_time);
							if (cur_time - time_start > 4) {
								args.splitter = false;
								result = 1;
								goto fin;
							}
							break;
						}
					}
					/* 分離対象以外をふるい落とす */
					code = split_ts(splitter, buf, rlen, &splitbuf);
					if (code != TSS_SUCCESS) {
						log << "split_ts failed" << std::endl;
						break;
					}
					break;
				}

				rlen = splitbuf.size;
				buf = splitbuf.buffer;
			fin:
				;
			}
#endif /* defined(TSSL) */

#ifdef UDP
			// UDP 配信
			udp.send(buf, rlen);
#endif /* defined(UDP) */

#ifdef HTTP
			while(rlen > 0) {
				ssize_t wc;
				int ws = rlen < SIZE_CHUNK ? rlen : SIZE_CHUNK;
				while(ws > 0) {
					wc = write(dest, buf, ws);
					if(wc < 0) {
						log << "write failed." << std::endl;
						rlen = 0;
						buf = NULL;
						break;
					}
					ws -= wc;
					rlen -= wc;
					buf += wc;
				}
			}
#else
			fwrite(buf, 1, rlen, dest);
#endif /* defined(HTTP) */

		} catch (usb_error& e) {
			if (urb_error_cnt <= URB_ERROR_MAX) {
				log << e.what() << std::endl;
				if (urb_error_cnt == URB_ERROR_MAX) {
					log << "Too many URB error." << std::endl;
				}
				urb_error_cnt++;
			}
		}
	}
	if (caughtSignal) {
#ifdef HTTP
		if( args.http_mode )
			caughtSignal = false;
		else
#endif /* defined(HTTP) */
		log << "interrupted." << std::endl;
	}
	// 受信スレッド停止
	tuner->stopStream();
	
	// シグナルハンドラを戻す。
	sigaction(SIGINT,  &saDefault, NULL);
	sigaction(SIGTERM, &saDefault, NULL);
	sigaction(SIGPIPE, &saDefault, NULL);

	rlen = 0;
	buf = NULL;

#ifdef B25
	// B25デコーダ内のデータを出力する。
	if (args.b25) {
		try {
			b25dec.flush();
			rlen = b25dec.get((const uint8_t **)&buf);
		} catch (b25_error& e) {
			log << "B25 Error: " << e.what() << std::endl;
			result = 1;
		}
	}
#endif /* defined(B25) */
#ifdef TSSL
	if (args.splitter) {
		splitbuf.size = 0;
		while (rlen) {
			/* 分離対象PIDの抽出 */
			if (split_select_finish != TSS_SUCCESS) {
				split_select_finish = split_select(splitter, buf, rlen);
				if (split_select_finish == TSS_NULL) {
					/* mallocエラー発生 */
					log << "split_select malloc failed" << std::endl;
					args.splitter = false;
					result = 1;
					break;
				} else if (split_select_finish != TSS_SUCCESS) {
					// 分離対象PIDが完全に抽出できるまで出力しない
					// 1秒程度余裕を見るといいかも
					time_t cur_time;
					time(&cur_time);
					if (cur_time - time_start > 4) {
						args.splitter = false;
						result = 1;
					}
					break;
				}
			}
			/* 分離対象以外をふるい落とす */
			code = split_ts(splitter, buf, rlen, &splitbuf);
			if (code != TSS_SUCCESS) {
				log << "split_ts failed" << std::endl;
				break;
			}
			break;
		}
		rlen = splitbuf.size;
		buf = splitbuf.buffer;
		split_shutdown(splitter);
	}
#endif /* defined(TSSL) */
#ifdef HTTP
		while(rlen > 0) {
			ssize_t wc;
			int ws = rlen < SIZE_CHUNK ? rlen : SIZE_CHUNK;
			while(ws > 0) {
				wc = write(dest, buf, ws);
				if(wc < 0) {
					log << "write failed." << std::endl;
					rlen = 0;
					buf = NULL;
					break;
				}
				ws -= wc;
				rlen -= wc;
				buf += wc;
			}
		}
		if( args.http_mode ){
			/* close http socket */
			close(dest);
			fprintf(stderr,"connection closed. still listening at port %d\n", args.http_port);
		}else
			break;
	}
#else
	if (0 < rlen) {
		fwrite(buf, 1, rlen, dest);
	}
#endif /* defined(HTTP) */

	// 時間計測
	timeval tv_end;
	if (gettimeofday(&tv_end, NULL) < 0) {
		err(1, "gettimeofday failed.");
	}
	
	// 出力先ファイルクローズ
#ifdef HTTP
	if (!args.stdout) {
		close(dest);
	}
#else
	fflush(dest);
	if (!args.stdout) {
		fclose(dest);
	}
#endif /* defined(HTTP) */
	log << "done." << std::endl;
	
#ifdef UDP
	// UDP クローズ
	udp.shutdown();
#endif /* defined(UDP) */
	
	// 録画時間出力
	timeval rec_time;
	timersub(&tv_end, &tv_start, &rec_time);
	log << "Rec time: " << rec_time.tv_sec << "." << std::setfill('0') << std::setw(6) << rec_time.tv_usec << " sec." << std::endl;
	
	// 終了時SignalLevel出力
	try {
		float lev_after = tuner->getSignalLevel();
		log << "Signal level: " << lev_after << std::endl;
	} catch (usb_error& e) {
		log << e.what() << " ignored." << std::endl;
	}
	
	return result;
}
Пример #5
0
BVHNode *BVHParser::parseNode( Buffer & buf, BVHNode * parent )
{
	BVHNode * node = new BVHNode();
	node->parent = parent;
	
	_linearNodes.push_back(node);
	
	buf.getToken(node->name);
	
	std::string str;
	
	buf.getToken(str);
	if( str != "{" )
	{
		debugPrint("Error didnt find opening bracket\n");
		delete node;
		return 0;
	}
	
	// parse offset
	buf.getToken(str);
	if(str!="OFFSET")
	{
		debugPrint("Error didnt find OFFSET\n");
		delete node;
		return 0;
	}
	
	buf.readLine(str);
	
	sscanf(str.c_str(),"%f %f %f",&node->offset.x,&node->offset.y,&node->offset.z);
	
	//buf.getToken(str);
	if(!buf.testToken("CHANNELS"))//, <#bool caseSensitive#>)str!="CHANNELS")
	{
		debugPrint("Error didnt find CHANNELS\n");
		delete node;
		return 0;
	}

	// parse channels 
	
	int nChannels = 0;
	
	buf.readInt(&nChannels);
	
	for( int i = 0; i < nChannels; i++ )
	{
		buf.getToken(str);
		BVH_CHANNEL chan = parseChannel(str);
		if(chan == CHANNEL_UNKNOWN) 
		{
			debugPrint("Error undefined channel %s\n",str.c_str());
			delete node;
			return 0;
		}
		node->channels.push_back(chan);
	}
	
	buf.getToken(str);
	
	// parse children ( if any... )
	while( str!="}" )
	{
		if( str=="JOINT" )
		{
			BVHNode * child = parseNode(buf,node);
			if(child==0)
			{
				debugPrint("Could not add child\n");
				delete node;
				return 0;
			}
			
			node->addChild(child);
			//buf.getToken(str);
		}
		else if( str=="End" )
		{
			buf.getToken(str); // skip site
			
			BVHNode * child = parseEndSite(buf,node);
			if(child==0)
			{
				debugPrint("Could not add child\n");
				delete node;
				return 0;
			}
			
			node->addChild(child);
		}
		
		buf.getToken(str);
	}
	
	// Hacky compute bone length...
	if( node->children.size() )
	{
		BVHNode * child = node->children[0];
	}
		
	return node;
}