/**
   * Internal helper to fork a process with handbrake and read the values from the process
   *
   * @param videoTranscoding
   * @return true: all ok; false: an error happend along the way
   */
  private boolean forkTranscodingProcess(VideoTranscoding videoTranscoding) {
    OLATResource video = videoTranscoding.getVideoResource();
    VideoModule videoModule = CoreSpringFactory.getImpl(VideoModule.class);
    VideoManager videoManager = CoreSpringFactory.getImpl(VideoManager.class);
    File masterFile = videoManager.getVideoFile(video);
    File transcodingFolder =
        ((LocalFolderImpl) videoManager.getTranscodingContainer(video)).getBasefile();
    File transcodedFile =
        new File(
            transcodingFolder,
            Integer.toString(videoTranscoding.getResolution()) + masterFile.getName());
    // mark this as beeing transcoded by this local transcoder
    videoTranscoding.setTranscoder(VideoTranscoding.TRANSCODER_LOCAL);
    videoTranscoding = videoManager.updateVideoTranscoding(videoTranscoding);

    ArrayList<String> cmd = new ArrayList<>();
    String tasksetConfig = videoModule.getTranscodingTasksetConfig();
    if (tasksetConfig != null && !"Mac OS X".equals(System.getProperty("os.name"))) {
      cmd.add("taskset");
      cmd.add("-c");
      cmd.add(tasksetConfig);
    }
    cmd.add("HandBrakeCLI");
    cmd.add("-i");
    cmd.add(masterFile.getAbsolutePath());
    cmd.add("-o");
    cmd.add(transcodedFile.getAbsolutePath());
    cmd.add("--optimize");
    cmd.add("--preset");
    cmd.add("Normal");
    cmd.add("--height");
    cmd.add(Integer.toString(videoTranscoding.getResolution()));
    cmd.add("--deinterlace");
    cmd.add("--crop");
    cmd.add("0:0:0:0");

    Process process = null;
    try {
      if (log.isDebug()) {
        log.debug(cmd.toString());
      }
      ProcessBuilder builder = new ProcessBuilder(cmd);
      process = builder.start();
      return updateVideoTranscodingFromProcessOutput(process, videoTranscoding, transcodedFile);
    } catch (IOException e) {
      log.error("Could not spawn convert sub process", e);
      return false;
    } finally {
      if (process != null) {
        process.destroy();
        process = null;
      }
    }
  }
 private boolean mayTranscode(int resolution) {
   if (!videoModule.isTranscodingEnabled()) {
     return false;
   }
   int[] transcodingRes = videoModule.getTranscodingResolutions();
   for (int i = 0; i < transcodingRes.length; i++) {
     if (resolution == transcodingRes[i]) {
       return true;
     }
   }
   return false;
 }
  /**
   * Implementation of job execution
   *
   * @param context
   * @return
   * @throws JobExecutionException
   */
  private boolean doExecute(JobExecutionContext context) throws JobExecutionException {
    VideoModule videoModule = CoreSpringFactory.getImpl(VideoModule.class);
    if (!videoModule.isTranscodingLocal()) {
      log.debug("Skipping execution of video transcoding job, local transcoding disabled");
      return false;
    }

    // Find first one to work with
    VideoManager videoManager = CoreSpringFactory.getImpl(VideoManager.class);
    List<VideoTranscoding> videoTranscodings =
        videoManager.getVideoTranscodingsPendingAndInProgress();
    VideoTranscoding videoTranscoding = null;
    for (VideoTranscoding videoTrans : videoTranscodings) {
      String transcoder = videoTrans.getTranscoder();
      if (transcoder == null) {
        log.info(
            "Start transcoding video with resolution::"
                + videoTrans.getResolution()
                + " for video resource::"
                + videoTrans.getVideoResource().getResourceableId());
        videoTrans.setTranscoder(VideoTranscoding.TRANSCODER_LOCAL);
        videoTranscoding = videoManager.updateVideoTranscoding(videoTrans);
        break;
      } else if (transcoder.equals(VideoTranscoding.TRANSCODER_LOCAL)) {
        log.info(
            "Continue with transcoding video with resolution::"
                + videoTrans.getResolution()
                + " for video resource::"
                + videoTrans.getVideoResource().getResourceableId());
        videoTranscoding = videoTrans;
        break;
      }
    }

    if (videoTranscoding == null) {
      log.debug(
          "Skipping execution of video transcoding job, no pending video transcoding found in database");
      return false;
    }
    // Ready transcode, forke process now
    boolean success = forkTranscodingProcess(videoTranscoding);

    // Transcoding done, call execution again until no more videos to be
    // processed. If an error happend, don't continue to not get into a loop
    if (success) {
      success = doExecute(context);
    }
    return success;
  }