Ejemplo n.º 1
0
  /**
   * A stateless method that validates an IMFEssenceComponent's header partition and verifies MXF
   * OP1A and IMF compliance. This could be utilized to perform preliminary validation of IMF
   * essences
   *
   * @param essencesHeaderPartitionPayloads - a list of IMF Essence Component header partition
   *     payloads
   * @return a list of errors encountered while performing compliance checks on the IMF Essence
   *     Component Header partition
   * @throws IOException - any I/O related error is exposed through an IOException
   */
  public static List<ErrorLogger.ErrorObject> validateIMFTrackFileHeaderMetadata(
      List<PayloadRecord> essencesHeaderPartitionPayloads) throws IOException {
    IMFErrorLogger imfErrorLogger = new IMFErrorLoggerImpl();
    List<PayloadRecord> essencesHeaderPartition =
        Collections.unmodifiableList(essencesHeaderPartitionPayloads);
    for (PayloadRecord payloadRecord : essencesHeaderPartition) {
      if (payloadRecord.getPayloadAssetType() != PayloadRecord.PayloadAssetType.EssencePartition) {
        imfErrorLogger.addError(
            IMFErrorLogger.IMFErrors.ErrorCodes.IMP_VALIDATOR_PAYLOAD_ERROR,
            IMFErrorLogger.IMFErrors.ErrorLevels.FATAL,
            String.format(
                "Payload asset type is %s, expected asset type %s",
                payloadRecord.getPayloadAssetType(),
                PayloadRecord.PayloadAssetType.EssencePartition.toString()));
        continue;
      }
      HeaderPartition headerPartition = null;
      try {
        headerPartition =
            new HeaderPartition(
                new ByteArrayDataProvider(payloadRecord.getPayload()),
                0L,
                (long) payloadRecord.getPayload().length,
                imfErrorLogger);

        MXFOperationalPattern1A.HeaderPartitionOP1A headerPartitionOP1A =
            MXFOperationalPattern1A.checkOperationalPattern1ACompliance(
                headerPartition, imfErrorLogger);
        IMFConstraints.checkIMFCompliance(headerPartitionOP1A, imfErrorLogger);
      } catch (IMFException | MXFException e) {
        if (headerPartition != null) {
          Preface preface = headerPartition.getPreface();
          GenericPackage genericPackage =
              preface.getContentStorage().getEssenceContainerDataList().get(0).getLinkedPackage();
          SourcePackage filePackage = (SourcePackage) genericPackage;
          UUID packageUUID = filePackage.getPackageMaterialNumberasUUID();
          imfErrorLogger.addError(
              new ErrorLogger.ErrorObject(
                  IMFErrorLogger.IMFErrors.ErrorCodes.IMF_ESSENCE_COMPONENT_ERROR,
                  IMFErrorLogger.IMFErrors.ErrorLevels.FATAL,
                  String.format(
                      "IMFTrackFile with ID %s has fatal errors", packageUUID.toString())));
        }
        if (e instanceof IMFException) {
          IMFException imfException = (IMFException) e;
          imfErrorLogger.addAllErrors(imfException.getErrors());
        } else if (e instanceof MXFException) {
          MXFException mxfException = (MXFException) e;
          imfErrorLogger.addAllErrors(mxfException.getErrors());
        }
      }
    }
    return imfErrorLogger.getErrors();
  }
Ejemplo n.º 2
0
  /**
   * A stateless method that returns the RFC-5646 Spoken Language Tag present in the Header
   * Partition of an Audio Essence
   *
   * @param essencesHeaderPartition - a list of payloads corresponding to the Header Partitions of
   *     TrackFiles that are a part of an Audio VirtualTrack
   * @param audioVirtualTrack - the audio virtual track whose spoken language needs to be
   *     ascertained
   * @return string corresponding to the RFC-5646 language tag present in the header partition of
   *     the Audio Essence
   * @throws IOException - any I/O related error is exposed through an IOException
   */
  @Nullable
  public static String getAudioTrackSpokenLanguage(
      VirtualTrack audioVirtualTrack, List<PayloadRecord> essencesHeaderPartition)
      throws IOException {
    IMFErrorLogger imfErrorLogger = new IMFErrorLoggerImpl();
    if (audioVirtualTrack.getSequenceTypeEnum() != Composition.SequenceTypeEnum.MainAudioSequence) {
      throw new IMFException(
          String.format(
              "Virtual track that was passed in is of type %s, spoken language is "
                  + "currently supported for only %s tracks",
              audioVirtualTrack.getSequenceTypeEnum().toString(),
              Composition.SequenceTypeEnum.MainAudioSequence.toString()));
    }
    List<VirtualTrack> virtualTracks = new ArrayList<>();
    virtualTracks.add(audioVirtualTrack);
    imfErrorLogger.addAllErrors(
        checkVirtualTrackAndEssencesHeaderPartitionPayloadRecords(
            virtualTracks, essencesHeaderPartition));
    if (imfErrorLogger.hasFatalErrors()) {
      throw new IMFException(
          String.format(
              "Fatal Errors were detected when trying to verify the Virtual Track and Essence Header Partition payloads %s",
              Utilities.serializeObjectCollectionToString(imfErrorLogger.getErrors())));
    }
    Set<String> audioLanguageSet = new HashSet<>();
    for (PayloadRecord payloadRecord : essencesHeaderPartition) {
      if (payloadRecord.getPayloadAssetType() != PayloadRecord.PayloadAssetType.EssencePartition) {
        throw new IMFException(
            String.format(
                "Payload asset type is %s, expected asset type %s",
                payloadRecord.getPayloadAssetType(),
                PayloadRecord.PayloadAssetType.EssencePartition.toString()),
            imfErrorLogger);
      }
      HeaderPartition headerPartition =
          new HeaderPartition(
              new ByteArrayDataProvider(payloadRecord.getPayload()),
              0L,
              (long) payloadRecord.getPayload().length,
              imfErrorLogger);
      audioLanguageSet.add(headerPartition.getAudioEssenceSpokenLanguage());
    }

    if (audioLanguageSet.size() > 1) {
      throw new IMFException(
          String.format(
              "It seems that RFC-5646 spoken language is not consistent across "
                  + "resources of this Audio Virtual Track, found references to %s languages in the HeaderPartition",
              Utilities.serializeObjectCollectionToString(audioLanguageSet)),
          imfErrorLogger);
    }
    return audioLanguageSet.iterator().next();
  }
Ejemplo n.º 3
0
  private static List<ErrorLogger.ErrorObject>
      checkVirtualTrackAndEssencesHeaderPartitionPayloadRecords(
          List<VirtualTrack> virtualTracks, List<PayloadRecord> essencesHeaderPartition)
          throws IOException {
    IMFErrorLogger imfErrorLogger = new IMFErrorLoggerImpl();
    Set<UUID> trackFileIDsSet = new HashSet<>();

    for (PayloadRecord payloadRecord : essencesHeaderPartition) {
      if (payloadRecord.getPayloadAssetType() != PayloadRecord.PayloadAssetType.EssencePartition) {
        throw new IMFException(
            String.format(
                "Payload asset type is %s, expected asset type %s",
                payloadRecord.getPayloadAssetType(),
                PayloadRecord.PayloadAssetType.EssencePartition.toString()),
            imfErrorLogger);
      }
      HeaderPartition headerPartition =
          new HeaderPartition(
              new ByteArrayDataProvider(payloadRecord.getPayload()),
              0L,
              (long) payloadRecord.getPayload().length,
              imfErrorLogger);
      try {
        /**
         * Add the Top Level Package UUID to the set of TrackFileIDs, this is required to validate
         * that the essences header partition that were passed in are in fact from the constituent
         * resources of the VirtualTack
         */
        MXFOperationalPattern1A.HeaderPartitionOP1A headerPartitionOP1A =
            MXFOperationalPattern1A.checkOperationalPattern1ACompliance(
                headerPartition, imfErrorLogger);
        IMFConstraints.HeaderPartitionIMF headerPartitionIMF =
            IMFConstraints.checkIMFCompliance(headerPartitionOP1A, imfErrorLogger);
        Preface preface =
            headerPartitionIMF.getHeaderPartitionOP1A().getHeaderPartition().getPreface();
        GenericPackage genericPackage =
            preface.getContentStorage().getEssenceContainerDataList().get(0).getLinkedPackage();
        SourcePackage filePackage = (SourcePackage) genericPackage;
        UUID packageUUID = filePackage.getPackageMaterialNumberasUUID();
        trackFileIDsSet.add(packageUUID);
      } catch (IMFException | MXFException e) {
        Preface preface = headerPartition.getPreface();
        GenericPackage genericPackage =
            preface.getContentStorage().getEssenceContainerDataList().get(0).getLinkedPackage();
        SourcePackage filePackage = (SourcePackage) genericPackage;
        UUID packageUUID = filePackage.getPackageMaterialNumberasUUID();
        imfErrorLogger.addError(
            new ErrorLogger.ErrorObject(
                IMFErrorLogger.IMFErrors.ErrorCodes.IMF_ESSENCE_COMPONENT_ERROR,
                IMFErrorLogger.IMFErrors.ErrorLevels.FATAL,
                String.format("IMFTrackFile with ID %s has fatal errors", packageUUID.toString())));
        if (e instanceof IMFException) {
          IMFException imfException = (IMFException) e;
          imfErrorLogger.addAllErrors(imfException.getErrors());
        } else if (e instanceof MXFException) {
          MXFException mxfException = (MXFException) e;
          imfErrorLogger.addAllErrors(mxfException.getErrors());
        }
      }
    }

    Set<UUID> virtualTrackResourceIDsSet = new HashSet<>();
    for (Composition.VirtualTrack virtualTrack : virtualTracks) {
      if (virtualTrack instanceof IMFEssenceComponentVirtualTrack) {
        virtualTrackResourceIDsSet.addAll(
            IMFEssenceComponentVirtualTrack.class.cast(virtualTrack).getTrackResourceIds());
      } else {
        imfErrorLogger.addError(
            IMFErrorLogger.IMFErrors.ErrorCodes.IMF_ESSENCE_COMPONENT_ERROR,
            IMFErrorLogger.IMFErrors.ErrorLevels.FATAL,
            String.format(
                "VirtualTrack with TrackId %s is not an Essence Component Virtual Track",
                virtualTrack.getTrackID().toString()));
      }
    }
    /**
     * Following check ensures that the Header Partitions corresponding to all the Resources of the
     * VirtualTracks were passed in.
     */
    Set<UUID> unreferencedResourceIDsSet = new HashSet<>();
    for (UUID uuid : virtualTrackResourceIDsSet) {
      if (!trackFileIDsSet.contains(uuid)) {
        unreferencedResourceIDsSet.add(uuid);
      }
    }
    if (unreferencedResourceIDsSet.size() > 0) {
      imfErrorLogger.addError(
          new ErrorLogger.ErrorObject(
              IMFErrorLogger.IMFErrors.ErrorCodes.IMP_VALIDATOR_PAYLOAD_ERROR,
              IMFErrorLogger.IMFErrors.ErrorLevels.FATAL,
              String.format(
                  "It seems that no EssenceHeaderPartition data was passed in for "
                      + "VirtualTrack Resource Ids %s, please verify that the correct Header Partition payloads for the "
                      + "Virtual Track were passed in",
                  Utilities.serializeObjectCollectionToString(unreferencedResourceIDsSet))));
    }

    /**
     * Following check ensures that the Header Partitions corresponding to only the Resource that
     * are a part of the VirtualTracks were passed in.
     */
    Set<UUID> unreferencedTrackFileIDsSet = new HashSet<>();
    for (UUID uuid : trackFileIDsSet) {
      if (!virtualTrackResourceIDsSet.contains(uuid)) {
        unreferencedTrackFileIDsSet.add(uuid);
      }
    }
    if (unreferencedTrackFileIDsSet.size() > 0) {
      imfErrorLogger.addError(
          new ErrorLogger.ErrorObject(
              IMFErrorLogger.IMFErrors.ErrorCodes.IMP_VALIDATOR_PAYLOAD_ERROR,
              IMFErrorLogger.IMFErrors.ErrorLevels.FATAL,
              String.format(
                  "It seems that EssenceHeaderPartition data was passed in for "
                      + "Resource Ids %s which are not part of this virtual track, please verify that only the Header "
                      + "Partition payloads for the Virtual Track were passed in",
                  Utilities.serializeObjectCollectionToString(unreferencedTrackFileIDsSet))));
    }

    return imfErrorLogger.getErrors();
  }