public void run() {

    SingletonForSSFMP info = null;
    SingletonForSSFMP2 info2 = null;
    SingletonForSSFMP3 info3 = null;

    switch (abs) {
      case 0:
        info = SingletonForSSFMP.getInstance();
        break;
      case 1:
        info2 = SingletonForSSFMP2.getInstance();
        break;
      case 2:
        info3 = SingletonForSSFMP3.getInstance();
        break;
      default:
        // info = SingletonForMyStreamer.getInstance();
        break;
    }

    int seqCapturedTimeShifted = 0; // info.getSeqTsOkkakeEncode();
    if ((abs == 0) && (info != null)) {
      info.getSeqTsCapturedTimeShifted();
    } else if ((abs == 1) && (info2 != null)) {
      info2.getSeqTsCapturedTimeShifted();
    } else if ((abs == 2) && (info3 != null)) {
      info3.getSeqTsCapturedTimeShifted();
    }

    String[] cmdArray = null;

    if (modeLive.equals("camV")) {

      if (videoProfile.equals("base")) {

        String[] cmdArrayBase = {
          FFMPEG_FOR_CAM,
          "-f",
          "video4linux2",
          "-s",
          capResolution,
          "-r",
          "30",
          "-i",
          "/dev/video0",
          "-s",
          videoResolution,
          // "-vcodec", "libx264", "-b:v", videoBitrate+"k", "-pix_fmt", "yuv420p",
          "-vcodec",
          "libx264",
          "-preset",
          "ultrafast",
          "-b:v",
          videoBitrate + "k",
          "-pix_fmt",
          "yuv420p",
          // "-coder", "0", "-bf", "0", "-pix_fmt", "yuv420p",
          "-threads",
          thread,
          "-t",
          durationLive,
          "-f",
          "mpegts",
          "-y",
          TEMP_PATH + FILE_SEPARATOR + "mystream" + videoBitrate + ".ts"
        };
        cmdArray = cmdArrayBase;

      } else if (videoProfile.equals("main")) {

        String[] cmdArrayMain = {
          // "-coder", "1", "-bf", "3", "-pix_fmt", "yuv420p",
        };
        cmdArray = cmdArrayMain;

      } else if (videoProfile.equals("high")) {

        String[] cmdArrayHigh = {
          // "-coder", "1", "-bf", "3", "-flags2", "dct8x8", "-pix_fmt", "yuv420p",
        };
        cmdArray = cmdArrayHigh;

      } else {

        //

      }

    } else if (modeLive.equals("camAV")) {

      if (videoProfile.equals("base")) {

        String[] cmdArrayBase = {
          FFMPEG_FOR_CAM,
          "-f",
          "video4linux2",
          "-s",
          capResolution,
          "-r",
          "30",
          "-i",
          "/dev/video0",
          "-f",
          "alsa",
          "-i",
          "hw:0,0",
          "-acodec",
          "libfaac",
          "-ab",
          "128k",
          "-ac",
          "2", // "-ar", "44100"
          "-s",
          videoResolution,
          "-vcodec",
          "libx264",
          "-preset",
          "ultrafast",
          "-b:v",
          videoBitrate + "k",
          "-pix_fmt",
          "yuv420p",
          // "-vcodec", "libx264", "-preset", "ultrafast", "-b:v", videoBitrate+"k",
          // "-vcodec", "libx264", "-profile:v", "baseline", "-level", "3.1", "-b:v",
          // videoBitrate+"k", "-pix_fmt", "yuv420p",
          "-threads",
          thread,
          "-t",
          durationLive,
          "-f",
          "mpegts",
          "-y",
          TEMP_PATH + FILE_SEPARATOR + "mystream" + videoBitrate + ".ts"
        };
        cmdArray = cmdArrayBase;

      } else if (videoProfile.equals("main")) {

        String[] cmdArrayMain = {};
        cmdArray = cmdArrayMain;

      } else if (videoProfile.equals("high")) {

        String[] cmdArrayHigh = {};
        cmdArray = cmdArrayHigh;

      } else {

        //

      }

    } else if (modeLive.equals("file")) {

      if (videoProfile.equals("base")) {

        String[] cmdArrayFileLive = {
          FFMPEG_FOR_FILE,
          "-i",
          FILE_PATH + FILE_SEPARATOR + file,
          "-acodec",
          audioCodec,
          "-ab",
          audioBitrate + "k",
          "-ar",
          audioSamplingFreq,
          "-ac",
          "2",
          "-s",
          videoResolution,
          //	"-vcodec", "libx264", "-profile:v", "baseline", "-level", "3.1", "-b:v",
          // videoBitrate+"k",
          "-vcodec",
          "libx264",
          "-profile:v",
          "baseline",
          "-level",
          "3.1",
          "-b:v",
          videoBitrate + "k",
          "-preset:v",
          "ultrafast",
          "-threads",
          thread,
          "-f",
          "mpegts",
          "-y",
          TEMP_PATH + FILE_SEPARATOR + "mystream" + videoBitrate + ".ts"
        };
        cmdArray = cmdArrayFileLive;

      } else if (videoProfile.equals("main")) {

        String[] cmdArrayFileLive = {};
        cmdArray = cmdArrayFileLive;

      } else if (videoProfile.equals("high")) {

        String[] cmdArrayFileLive = {};
        cmdArray = cmdArrayFileLive;

      } else {

        //

      }

    } else if (modeLive.equals("captured")) {

      if (videoProfile.equals("base")) {

        String[] cmdArrayPt2Live = {
          FFMPEG_FOR_FILE,
          "-i",
          CAP_PATH + FILE_SEPARATOR + capFile,
          "-acodec",
          audioCodec,
          "-ab",
          audioBitrate + "k",
          "-ar",
          audioSamplingFreq,
          "-ac",
          "2",
          "-s",
          videoResolution,
          "-vcodec",
          "libx264",
          "-profile:v",
          "baseline",
          "-level",
          "3.1",
          "-b:v",
          videoBitrate + "k",
          "-threads",
          thread,
          "-f",
          "mpegts",
          "-y",
          TEMP_PATH + FILE_SEPARATOR + "mystream" + videoBitrate + ".ts"
        };
        cmdArray = cmdArrayPt2Live;

      } else if (videoProfile.equals("main")) {

        String[] cmdArrayPt2Live = {};
        cmdArray = cmdArrayPt2Live;

      } else if (videoProfile.equals("high")) {

        String[] cmdArrayPt2Live = {};
        cmdArray = cmdArrayPt2Live;

      } else {

        //

      }

    } else if (modeLive.equals("capturedTimeShifted")) {

      if (encOrNot.equals("1") || encOrNot.equals("3")) {

        if (videoProfile.equals("base")) {

          String[] cmdArrayPt2Live = {
            "ffmpeg",
            "-i",
            TEMP_PATH_FOR_ENC + FILE_SEPARATOR + "fileSequence" + seqCapturedTimeShifted + ".ts",
            "-acodec",
            audioCodec,
            "-ab",
            audioBitrate + "k",
            "-ar",
            audioSamplingFreq,
            "-ac",
            "2",
            "-s",
            videoResolution,
            "-vcodec",
            "libx264",
            "-profile:v",
            "baseline",
            "-level",
            "3.1",
            "-b:v",
            videoBitrate + "k",
            "-threads",
            thread,
            "-f",
            "mpegts",
            "-y",
            TEMP_PATH_FOR_ENC
                + FILE_SEPARATOR
                + "fileSequenceEncoded"
                + seqCapturedTimeShifted
                + ".ts"
          };
          cmdArray = cmdArrayPt2Live;

        } else if (videoProfile.equals("main")) {

          String[] cmdArrayPt2Live = {};
          cmdArray = cmdArrayPt2Live;

        } else if (videoProfile.equals("high")) {

          String[] cmdArrayPt2Live = {};
          cmdArray = cmdArrayPt2Live;

        } else {

        }

      } else if (encOrNot.equals("2") || encOrNot.equals("4")) {

        if (videoProfile.equals("base")) {

          String[] cmdArrayPt2Live = {
            FFMPEG_FOR_FILE,
            "-i",
            TEMP_PATH_FOR_ENC + FILE_SEPARATOR + "fileSequence" + seqCapturedTimeShifted + ".ts",
            "-acodec",
            audioCodec,
            "-ab",
            audioBitrate + "k",
            "-ar",
            audioSamplingFreq,
            "-ac",
            "2",
            "-s",
            videoResolution,
            "-vcodec",
            "libx264",
            "-profile:v",
            "baseline",
            "-level",
            "3.1",
            "-b:v",
            videoBitrate + "k",
            "-threads",
            thread,
            "-f",
            "mpegts",
            "-y",
            streamPath + FILE_SEPARATOR + "fileSequence" + seqCapturedTimeShifted + ".ts"
          };
          cmdArray = cmdArrayPt2Live;

        } else if (videoProfile.equals("main")) {

          String[] cmdArrayPt2Live = {};
          cmdArray = cmdArrayPt2Live;

        } else if (videoProfile.equals("high")) {

          String[] cmdArrayPt2Live = {};
          cmdArray = cmdArrayPt2Live;

        } else {

          //

        }

      } else {

        //
      }

    } else {

      //

    }

    String cmd = "";
    for (int i = 0; i < cmdArray.length; i++) {
      cmd += cmdArray[i] + " ";
    }
    log.debug(
        MARKER_FFmpegRunner,
        "{} {}",
        Thread.currentThread().getStackTrace()[1].getMethodName(),
        cmd);

    ProcessBuilder pb = new ProcessBuilder(cmdArray);
    try {

      log.debug(
          MARKER_FFmpegRunner,
          "{} Begin FFmpeg!",
          Thread.currentThread().getStackTrace()[1].getMethodName());
      Process pr = pb.start();
      InputStream is = pr.getErrorStream();
      InputStreamReader isr = new InputStreamReader(is);
      BufferedReader br = new BufferedReader(isr);

      String str = "";
      while ((str = br.readLine()) != null) {
        log.debug(
            MARKER_FFmpegRunner,
            "{} : {} {}",
            abs,
            Thread.currentThread().getStackTrace()[1].getMethodName(),
            str);
      }
      br.close();
      isr.close();
      is.close();
      pr.destroy();
      pr = null;
      pb = null;
      log.debug(
          MARKER_FFmpegRunner,
          "{} End FFmpeg!",
          Thread.currentThread().getStackTrace()[1].getMethodName());

      // TODO remove 処理が冗長すぎる.
      if (!modeLive.equals("capturedTimeShifted")) {

        if ((abs == 0) && (info != null) && SingletonForSSFMP.getInstance().getFlagRemoveFile()) {
          if ((info2 == null) && (info3 == null)) {
            Remover r = new Remover(0);
            r.doRemove();
          } else if ((info2 != null) && (info3 == null)) {
            if (SingletonForSSFMP2.getInstance().getFlagRemoveFile()) {
              Remover r = new Remover(1);
              r.doRemove();
            }
          } else if ((info2 == null) && (info3 != null)) {
            if (SingletonForSSFMP3.getInstance().getFlagRemoveFile()) {
              Remover r = new Remover(1);
              r.doRemove();
            }
          } else if ((info2 != null) && (info3 != null)) {
            if (SingletonForSSFMP2.getInstance().getFlagRemoveFile()
                && SingletonForSSFMP3.getInstance().getFlagRemoveFile()) {
              Remover r = new Remover(1);
              r.doRemove();
            }
          }
        } else if ((abs == 1) && (info2 != null)) {
          if (SingletonForSSFMP.getInstance().getFlagRemoveFile()
              && SingletonForSSFMP2.getInstance().getFlagRemoveFile()
              && SingletonForSSFMP3.getInstance().getFlagRemoveFile()) {
            Remover r = new Remover(1);
            r.doRemove();
          }
        } else if ((abs == 2) && (info3 != null)) {
          if (SingletonForSSFMP.getInstance().getFlagRemoveFile()
              && SingletonForSSFMP2.getInstance().getFlagRemoveFile()
              && SingletonForSSFMP3.getInstance().getFlagRemoveFile()) {
            Remover r = new Remover(1);
            r.doRemove();
          }
        }

      } else if (modeLive.equals("capturedTimeShifted")) {

        log.debug(
            MARKER_FFmpegRunner,
            "{} finish, capturedTimeShifted",
            Thread.currentThread().getStackTrace()[1].getMethodName());

        if ((abs == 0) && (info != null)) {
          if ((encOrNot.equals("1") || encOrNot.equals("3"))
              && !SingletonForSSFMP.getInstance().getFlagRemoveFile()) {
            log.debug(
                MARKER_FFmpegRunner,
                "{} -> Encrypter",
                Thread.currentThread().getStackTrace()[1].getMethodName());
            SingletonForSSFMP.getInstance().setSeqTsCapturedTimeShifted(seqCapturedTimeShifted);

            Encrypter ec =
                new Encrypter(streamPath, TEMP_PATH_FOR_ENC, modeLive, abs, MPEG2_TS_PACKET_LENGTH);
            Thread ecThread = new Thread(ec);
            ecThread.start();
          }
        }

        if ((abs == 1) && (info2 != null)) {
          if ((encOrNot.equals("1") || encOrNot.equals("3"))
              && !SingletonForSSFMP2.getInstance().getFlagRemoveFile()) {
            log.debug(
                MARKER_FFmpegRunner,
                "{} -> Encrypter",
                Thread.currentThread().getStackTrace()[1].getMethodName());
            SingletonForSSFMP2.getInstance().setSeqTsCapturedTimeShifted(seqCapturedTimeShifted);

            Encrypter ec =
                new Encrypter(streamPath, TEMP_PATH_FOR_ENC, modeLive, abs, MPEG2_TS_PACKET_LENGTH);
            Thread ecThread = new Thread(ec);
            ecThread.start();
          }
        }

        if ((abs == 2) && (info3 != null)) {
          if ((encOrNot.equals("1") || encOrNot.equals("3"))
              && !SingletonForSSFMP3.getInstance().getFlagRemoveFile()) {
            log.debug(
                MARKER_FFmpegRunner,
                "{} -> Encrypter",
                Thread.currentThread().getStackTrace()[1].getMethodName());
            SingletonForSSFMP3.getInstance().setSeqTsCapturedTimeShifted(seqCapturedTimeShifted);

            Encrypter ec =
                new Encrypter(streamPath, TEMP_PATH_FOR_ENC, modeLive, abs, MPEG2_TS_PACKET_LENGTH);
            Thread ecThread = new Thread(ec);
            ecThread.start();
          }
        }

        if (info2 == null && info3 == null) {
          if (SingletonForSSFMP.getInstance().getFlagRemoveFile()) {
            Remover r = new Remover(0);
            r.doRemove();
            SingletonForSSFMP.getInstance().setFlagRemoveFile(0);
            log.debug(
                MARKER_FFmpegRunner,
                "{} capturedTimeShifted - canceller - FFmepgRunner calls remover type1",
                Thread.currentThread().getStackTrace()[1].getMethodName());
          }
        }
        if (info2 != null && info3 == null) {
          if (SingletonForSSFMP.getInstance().getFlagRemoveFile()
              && SingletonForSSFMP2.getInstance().getFlagRemoveFile()) {
            Remover r = new Remover(1);
            r.doRemove();
            SingletonForSSFMP.getInstance().setFlagRemoveFile(0);
            SingletonForSSFMP2.getInstance().setFlagRemoveFile(0);
            log.debug(
                MARKER_FFmpegRunner,
                "{} capturedTimeShifted - canceller - FFmepgRunner calls remover type2",
                Thread.currentThread().getStackTrace()[1].getMethodName());
          }
        }
        if (info2 == null && info3 != null) {
          if (SingletonForSSFMP.getInstance().getFlagRemoveFile()
              && SingletonForSSFMP3.getInstance().getFlagRemoveFile()) {
            Remover r = new Remover(1);
            r.doRemove();
            SingletonForSSFMP.getInstance().setFlagRemoveFile(0);
            SingletonForSSFMP3.getInstance().setFlagRemoveFile(0);
            log.debug(
                MARKER_FFmpegRunner,
                "{} capturedTimeShifted - canceller - FFmepgRunner calls remover type2",
                Thread.currentThread().getStackTrace()[1].getMethodName());
          }
        }
        if (info2 != null && info3 != null) {
          if (SingletonForSSFMP.getInstance().getFlagRemoveFile()
              && SingletonForSSFMP2.getInstance().getFlagRemoveFile()
              && SingletonForSSFMP3.getInstance().getFlagRemoveFile()) {
            Remover r = new Remover(1);
            r.doRemove();
            info.setFlagRemoveFile(0);
            info2.setFlagRemoveFile(0);
            info3.setFlagRemoveFile(0);
            log.debug(
                MARKER_FFmpegRunner,
                "{} capturedTimeShifted - canceller - FFmepgRunner calls remover type2",
                Thread.currentThread().getStackTrace()[1].getMethodName());
          }
        }
      }

    } catch (IOException e) {
      e.printStackTrace();
    } // try
  } // run
  public void _testGetPutRemove() throws Exception {

    List<NodeData> nodes = prepare();

    Set<Reader> readers = new HashSet<Reader>();
    Set<Writer> writers = new HashSet<Writer>();
    Set<Remover> removers = new HashSet<Remover>();
    long start = System.currentTimeMillis();
    try {
      // create readers
      for (int t = 1; t <= 100; t++) {
        NodeData[] ns = new NodeData[nodes.size()];
        nodes.toArray(ns);
        Reader r = new Reader(ns, "reader #" + t);
        readers.add(r);
        r.start();
      }

      // create writers
      for (int t = 1; t <= 5; t++) {
        NodeData[] ns = new NodeData[nodes.size()];
        nodes.toArray(ns);
        Writer w = new Writer(ns, "writer #" + t, 1000);
        writers.add(w);
        w.start();
      }

      // create removers
      for (int t = 1; t <= 5; t++) {
        NodeData[] ns = new NodeData[nodes.size()];
        nodes.toArray(ns);
        Remover r = new Remover(ns, "remover #" + t, 1000);
        removers.add(r);
        r.start();
      }

      log.info("Wait....");

      // Thread.sleep(50400 * 1000); // 50400sec = 14h
      Thread.sleep(20 * 1000); // 20sec.

      log.info("Stopping");
    } finally {
      // join
      for (Remover r : removers) {
        r.cancel();
        r.join();
      }

      for (Writer w : writers) {
        w.cancel();
        w.join();
      }

      for (Reader r : readers) {
        r.cancel();
        r.join();
      }

      // debug result
      long stop = System.currentTimeMillis() - start;
      long totalRead = 0;
      for (Reader r : readers) {
        totalRead += r.itemsProcessed;
        // log.info(r.getName() + " " + (r.itemsProcessed));
      }

      for (Writer w : writers) {
        totalRead += w.itemsProcessed;
        // log.info(w.getName() + " " + (w.itemsProcessed));
      }

      for (Remover r : removers) {
        totalRead += r.itemsProcessed;
        // log.info(r.getName() + " " + (r.itemsProcessed));
      }

      double speed = totalRead * 1d / stop;
      log.info(
          "Total accessed "
              + totalRead
              + ", speed "
              + speed
              + " oper/sec., time "
              + (stop / 1000d)
              + "sec");
    }
  }