/**
   * Gets the <tt>MediaFormat</tt>s supported by this <tt>MediaFormatFactory</tt> and the
   * <tt>MediaService</tt> associated with it and having the specified <tt>encoding</tt> and,
   * optionally, <tt>clockRate</tt>.
   *
   * @param encoding the well-known encoding (name) of the <tt>MediaFormat</tt>s to be retrieved
   * @param clockRate the clock rate of the <tt>MediaFormat</tt>s to be retrieved; {@link
   *     #CLOCK_RATE_NOT_SPECIFIED} if any clock rate is acceptable
   * @return a <tt>List</tt> of the <tt>MediaFormat</tt>s supported by the <tt>MediaService</tt>
   *     associated with this <tt>MediaFormatFactory</tt> and having the specified encoding and,
   *     optionally, clock rate
   */
  private List<MediaFormat> getSupportedMediaFormats(String encoding, double clockRate) {
    EncodingConfiguration encodingConfiguration =
        NeomediaServiceUtils.getMediaServiceImpl().getCurrentEncodingConfiguration();
    List<MediaFormat> supportedMediaFormats =
        getMatchingMediaFormats(
            encodingConfiguration.getAllEncodings(MediaType.AUDIO), encoding, clockRate);

    if (supportedMediaFormats.isEmpty())
      supportedMediaFormats =
          getMatchingMediaFormats(
              encodingConfiguration.getAllEncodings(MediaType.VIDEO), encoding, clockRate);
    return supportedMediaFormats;
  }
  private void setPriorities(int[] priorities) {
    final int count = encodings.length;

    if (priorities.length != count) throw new IllegalArgumentException("priorities");
    for (int i = 0; i < count; i++) {
      encodingConfiguration.setPriority(encodings[i], priorities[i]);
    }
  }
  private MediaFormat[] getEncodings() {
    if (encodings != null) return encodings;

    MediaFormat[] availableEncodings = encodingConfiguration.getAllEncodings(type);
    int encodingCount = availableEncodings.length;

    if (encodingCount < 1) encodings = MediaUtils.EMPTY_MEDIA_FORMATS;
    else {
      /*
       * The MediaFormats will be displayed by encoding (name) and clock
       * rate and EncodingConfiguration will store them that way so this
       * TableModel should better display unique encoding-clock rate
       * pairs.
       */
      HashMap<String, MediaFormat> availableEncodingSet = new HashMap<String, MediaFormat>();

      for (MediaFormat availableEncoding : availableEncodings) {
        availableEncodingSet.put(
            availableEncoding.getEncoding() + "/" + availableEncoding.getClockRateString(),
            availableEncoding);
      }
      availableEncodings = availableEncodingSet.values().toArray(MediaUtils.EMPTY_MEDIA_FORMATS);
      encodingCount = availableEncodings.length;

      encodings = new MediaFormat[encodingCount];
      System.arraycopy(availableEncodings, 0, encodings, 0, encodingCount);
      // Display the encodings in decreasing priority.
      Arrays.sort(
          encodings,
          0,
          encodingCount,
          new Comparator<MediaFormat>() {
            public int compare(MediaFormat format0, MediaFormat format1) {
              int ret =
                  encodingConfiguration.getPriority(format1)
                      - encodingConfiguration.getPriority(format0);

              if (ret == 0) {
                /*
                 * In the cases of equal priorities, display them
                 * sorted by encoding name in increasing order.
                 */
                ret = format0.getEncoding().compareToIgnoreCase(format1.getEncoding());
                if (ret == 0) {
                  /*
                   * In the cases of equal priorities and equal
                   * encoding names, display them sorted by clock
                   * rate in decreasing order.
                   */
                  ret = Double.compare(format1.getClockRate(), format0.getClockRate());
                }
              }
              return ret;
            }
          });
    }
    return encodings;
  }
  private int[] getPriorities() {
    MediaFormat[] encodings = getEncodings();
    final int count = encodings.length;
    int[] priorities = new int[count];

    for (int i = 0; i < count; i++) {
      int priority = encodingConfiguration.getPriority(encodings[i]);

      priorities[i] = (priority > 0) ? (count - i) : 0;
    }
    return priorities;
  }
  @Override
  public void setValueAt(Object value, int rowIndex, int columnIndex) {
    if ((columnIndex == 0) && (value instanceof Boolean)) {
      int priority = ((Boolean) value) ? (getPriorities().length - rowIndex) : 0;
      MediaFormat encoding = encodings[rowIndex];

      // We fire the update event before setting the configuration
      // property in order to have more reactive user interface.
      fireTableCellUpdated(rowIndex, columnIndex);

      encodingConfiguration.setPriority(encoding, priority);
    }
  }
  public Object getValueAt(int rowIndex, int columnIndex) {
    MediaFormat encoding = getEncodings()[rowIndex];

    switch (columnIndex) {
      case 0:
        return (encodingConfiguration.getPriority(encoding) > 0);
      case 1:
        if (MediaType.VIDEO.equals(encoding.getMediaType())
            && (VideoMediaFormatImpl.DEFAULT_CLOCK_RATE == encoding.getClockRate()))
          return encoding.getEncoding();
        else {
          return encoding.getEncoding() + "/" + encoding.getRealUsedClockRateString();
        }
      default:
        return null;
    }
  }