/** Try different transcoded formats for concatenation. */
  public boolean tryTranscode(
      ProcInfo pInfo[], int procID, int type, int trackID, Format candidate) {
    if (procID >= pInfo.length) return true;

    boolean matched = false;
    TrackControl tc = pInfo[procID].tracksByType[type][trackID].tc;
    Format supported[] = tc.getSupportedFormats();

    for (int i = 0; i < supported.length; i++) {
      if (candidate.matches(supported[i])
          && tryTranscode(pInfo, procID + 1, type, trackID, candidate)) {
        matched = true;
        break;
      }
    }

    return matched;
  }
  /** Try matching the data formats and find common ones for concatenation. */
  public boolean tryMatch(ProcInfo pInfo[], int type, int trackID) {
    TrackControl tc = pInfo[0].tracksByType[type][trackID].tc;
    Format origFmt = tc.getFormat();
    Format newFmt, oldFmt;
    Format supported[] = tc.getSupportedFormats();

    for (int i = 0; i < supported.length; i++) {

      if (supported[i] instanceof AudioFormat) {
        // If it's not the original format, then for audio, we'll
        // only do linear since it's more accurate to compute the
        // audio times.
        if (!supported[i].matches(tc.getFormat())
            && !supported[i].getEncoding().equalsIgnoreCase(AudioFormat.LINEAR)) continue;
      }

      if (tryTranscode(pInfo, 1, type, trackID, supported[i])) {

        // We've found the right format to transcode all the
        // tracks to. We'll set it on the corresponding
        // TrackControl on each processor.

        for (int j = 0; j < pInfo.length; j++) {
          tc = pInfo[j].tracksByType[type][trackID].tc;
          oldFmt = tc.getFormat();
          newFmt = supported[i];

          // Check if it requires transcoding.
          if (!oldFmt.matches(newFmt)) {
            if (!transcodeMsg) {
              transcodeMsg = true;
              System.err.println(TRANSCODE_MSG);
            }

            System.err.println("- Transcoding: " + pInfo[j].ml);
            System.err.println("  " + oldFmt);
            System.err.println("           to:");
            System.err.println("  " + newFmt);
          }

          // For video, check if it requires scaling.
          if (oldFmt instanceof VideoFormat) {
            Dimension newSize = ((VideoFormat) origFmt).getSize();
            Dimension oldSize = ((VideoFormat) oldFmt).getSize();

            if (oldSize != null && !oldSize.equals(newSize)) {
              // It requires scaling.

              if (!transcodeMsg) {
                transcodeMsg = true;
                System.err.println(TRANSCODE_MSG);
              }
              System.err.println("- Scaling: " + pInfo[j].ml);
              System.err.println("  from: " + oldSize.width + " x " + oldSize.height);
              System.err.println("  to: " + newSize.width + " x " + newSize.height);
              newFmt =
                  (new VideoFormat(null, newSize, Format.NOT_SPECIFIED, null, Format.NOT_SPECIFIED))
                      .intersects(newFmt);
            }
          }
          tc.setFormat(newFmt);
        }

        return true;
      }
    }

    return false;
  }