/* * myLib - https://github.com/taktod/myLib * Copyright (c) 2014 ttProject. All rights reserved. * * Licensed under The MIT license. */ package com.ttProject.transcode.ffmpeg.worker; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; import org.apache.log4j.Logger; import com.ttProject.transcode.ffmpeg.FfmpegTranscodeManager; /** * データの受信処理 * @author taktod */ public class DataReceiveWorker implements Runnable { /** 動作ロガー */ private final Logger logger = Logger.getLogger(DataReceiveWorker.class); /** 動作読み込みstream */ private final InputStream is; /** 動作読み込みチャンネル */ private final ReadableByteChannel outputChannel; /** 処理転送先listener */ private boolean workFlg = true; /** 動作させるexecutor */ private ExecutorService loopExecutor = null; /** データを戻す処理本体 */ private final FfmpegTranscodeManager transcodeManager; /** 処理終了フラグ(このフラグが立っている状態で1秒データ転送がなければ殺します) */ private boolean endFlg = false; /** 最終処理時刻 */ private long lastTaskTime = -1; /** * コンストラクタ * @param outputChannel */ public DataReceiveWorker(FfmpegTranscodeManager transcodeManagaer, InputStream is) { this.transcodeManager = transcodeManagaer; this.is = is; this.outputChannel = Channels.newChannel(is); } /** * 処理に利用するexecutorを設定 * @param executor */ public void setExecutor(ExecutorService executor) { loopExecutor = executor; } /** * 開始します */ public void start() { if(loopExecutor == null) { loopExecutor = Executors.newSingleThreadExecutor(); } loopExecutor.execute(this); } public void waitForEnd() { System.out.println("おわりがみえた!?"); endFlg = true; } /** * 停止処理 */ public void close() { } /** * 動作実体 */ @Override public void run() { try { boolean readFlg = false; if(is.available() != 0) { ByteBuffer buffer = ByteBuffer.allocate(65536); outputChannel.read(buffer); // このreadがlockするらしい。 buffer.flip(); readFlg = buffer.remaining() != 0; if(readFlg) { lastTaskTime = System.currentTimeMillis(); } // unit化を実行 transcodeManager.process(transcodeManager.getUnitizer().getUnits(buffer)); } if(endFlg && System.currentTimeMillis() - lastTaskTime > 1000) { // 強制的におわらせます。 logger.info("データがこなくなってから1秒たったので、とめます。"); transcodeManager.close(); workFlg = false; } if(workFlg) { if(!readFlg) { if(loopExecutor instanceof ThreadPoolExecutor) { ThreadPoolExecutor threadExecutor = (ThreadPoolExecutor) loopExecutor; if(threadExecutor.getQueue().size() == 0) { // queueのデータがない場合はちょっと待つ Thread.sleep(100); } } } // 再度実行させる loopExecutor.execute(this); } } catch(Exception e) { logger.error("例外が発生して、読み込みスレッドがとまりました。", e); } } }