Example #1
0
  /**
   * A stateless method that determines if 2 or more Composition documents corresponding to the same
   * title can be inferred to represent the same presentation timeline. This method is present to
   * work around current limitations in the IMF eco system wherein CPL's might not be built
   * incrementally to include all the IMF essences that are a part of the same timeline
   *
   * @param referenceCPLPayloadRecord - a payload record corresponding to a Reference Composition
   *     document, perhaps the first composition playlist document that was delivered for a
   *     particular composition.
   * @param cplPayloads - a list of payload records corresponding to each of the Composition
   *     documents that need to be verified for mergeability
   * @return a boolean indicating if the CPLs can be merged or not
   * @throws IOException - any I/O related error is exposed through an IOException
   */
  public static List<ErrorLogger.ErrorObject> isCPLMergeable(
      PayloadRecord referenceCPLPayloadRecord, List<PayloadRecord> cplPayloads) throws IOException {

    IMFErrorLogger imfErrorLogger = new IMFErrorLoggerImpl();
    List<PayloadRecord> cplPayloadRecords = Collections.unmodifiableList(cplPayloads);
    List<Composition> compositions = new ArrayList<>();
    try {
      compositions.add(
          new Composition(new ByteArrayByteRangeProvider(referenceCPLPayloadRecord.getPayload())));
    } catch (IMFException e) {
      imfErrorLogger.addAllErrors(e.getErrors());
    }

    for (PayloadRecord cpl : cplPayloadRecords) {
      try {
        compositions.add(new Composition(new ByteArrayByteRangeProvider(cpl.getPayload())));
      } catch (IMFException e) {
        imfErrorLogger.addAllErrors(e.getErrors());
      }
    }

    if (imfErrorLogger.hasFatalErrors()) {
      return imfErrorLogger.getErrors();
    }

    VirtualTrack referenceVideoVirtualTrack = compositions.get(0).getVideoVirtualTrack();
    UUID referenceCPLUUID = compositions.get(0).getUUID();
    for (int i = 1; i < compositions.size(); i++) {
      if (!referenceVideoVirtualTrack.equivalent(compositions.get(i).getVideoVirtualTrack())) {
        imfErrorLogger.addError(
            IMFErrorLogger.IMFErrors.ErrorCodes.IMF_CPL_ERROR,
            IMFErrorLogger.IMFErrors.ErrorLevels.WARNING,
            String.format(
                "CPL Id %s can't be merged with Reference CPL Id %s, since the video virtual tracks do not seem to represent the same timeline.",
                compositions.get(i).getUUID(), referenceCPLUUID));
      }
    }

    /**
     * Perform AudioTrack mergeability checks 1) Identify AudioTracks that are the same language 2)
     * Compare language tracks to see if they represent the same timeline
     */
    Boolean bAudioVirtualTrackMapFail = false;
    List<Map<Set<DOMNodeObjectModel>, ? extends VirtualTrack>> audioVirtualTracksMapList =
        new ArrayList<>();
    for (Composition composition : compositions) {
      try {
        audioVirtualTracksMapList.add(composition.getAudioVirtualTracksMap());
      } catch (IMFException e) {
        bAudioVirtualTrackMapFail = false;
        imfErrorLogger.addAllErrors(e.getErrors());
      }
    }

    if (!bAudioVirtualTrackMapFail) {
      Map<Set<DOMNodeObjectModel>, ? extends VirtualTrack> referenceAudioVirtualTracksMap =
          audioVirtualTracksMapList.get(0);
      for (int i = 1; i < audioVirtualTracksMapList.size(); i++) {
        if (!compareAudioVirtualTrackMaps(
            Collections.unmodifiableMap(referenceAudioVirtualTracksMap),
            Collections.unmodifiableMap(audioVirtualTracksMapList.get(i)),
            imfErrorLogger)) {
          imfErrorLogger.addError(
              IMFErrorLogger.IMFErrors.ErrorCodes.IMF_CPL_ERROR,
              IMFErrorLogger.IMFErrors.ErrorLevels.WARNING,
              String.format(
                  "CPL Id %s can't be merged with Reference CPL Id %s, since 2 same language audio tracks do not seem to represent the same timeline.",
                  compositions.get(i).getUUID(), referenceCPLUUID));
        }
      }
    }

    /** Perform MarkerTrack mergeability checks */
    Composition.VirtualTrack referenceMarkerVirtualTrack =
        compositions.get(0).getMarkerVirtualTrack();
    if (referenceMarkerVirtualTrack != null) {
      UUID referenceMarkerCPLUUID = compositions.get(0).getUUID();
      for (int i = 1; i < compositions.size(); i++) {
        if (!referenceVideoVirtualTrack.equivalent(compositions.get(i).getMarkerVirtualTrack())) {
          imfErrorLogger.addError(
              IMFErrorLogger.IMFErrors.ErrorCodes.IMF_CPL_ERROR,
              IMFErrorLogger.IMFErrors.ErrorLevels.WARNING,
              String.format(
                  "CPL Id %s can't be merged with Reference CPL Id %s, since the marker virtual tracks do not seem to represent the same timeline.",
                  compositions.get(i).getUUID(), referenceMarkerCPLUUID));
        }
      }
    }

    return imfErrorLogger.getErrors();
  }