Ejemplo n.º 1
0
void XMPMetadataSource::loadReference(const MetaString& thisRefPath, const shared_ptr<Metadata>& md, MetadataStream& stream)
{
    XMP_Int64 id;
    MetaString tmpPath;
    MetaString refName;
    SXMPUtils::ComposeStructFieldPath(VMF_NS, thisRefPath.c_str(), VMF_NS, REF_NAME, &tmpPath);
    if (!xmp->GetProperty(VMF_NS, tmpPath.c_str(), &refName, nullptr))
        refName = "";
    
    SXMPUtils::ComposeStructFieldPath(VMF_NS, thisRefPath.c_str(), VMF_NS, REF_ID, &tmpPath);
    if (!xmp->GetProperty_Int64(VMF_NS, tmpPath.c_str(), &id, nullptr))
    {
        VMF_EXCEPTION(DataStorageException, "Broken reference by path" + thisRefPath);
    }

    IdType realId = id;
    shared_ptr<Metadata> refTo = stream.getById(realId);
    if (!refTo)
    {
        auto it = idMap.find(realId);
        if (it == idMap.end())
        {
            VMF_EXCEPTION(DataStorageException, "Undefined reference by path " + thisRefPath);
        }
        InternalPath path = it->second;
        std::shared_ptr<MetadataSchema> refSchemaDesc = stream.getSchema(path.schema);
        std::shared_ptr<MetadataDesc> refMetadataDesc = refSchemaDesc->findMetadataDesc(path.metadata);
        loadMetadata(path.path, refMetadataDesc, stream);
        refTo = stream.getById(realId);
    }
    md->addReference(refTo, refName);
}
Ejemplo n.º 2
0
std::shared_ptr<Metadata> MetadataStream::import( MetadataStream& srcStream, std::shared_ptr< Metadata >& spMetadata, std::map< IdType, IdType >& mapIds, long long nTarFrameIndex, long long nSrcFrameIndex, long long nNumOfFrames )
{
    auto nSrcMetadataId = spMetadata->getId();

    // Check to make sure the metadata belongs to the source stream
    if( nSrcMetadataId < 0 || srcStream.getById( nSrcMetadataId ) != spMetadata )
    {
        VMF_EXCEPTION(IncorrectParamException, "The input metadata does not belong to the source stream!" );
    }

    // Skip if it has already been imported
    if( mapIds.find( nSrcMetadataId ) != mapIds.end() )
    {
        auto spNewMetadata = this->getById( mapIds[ nSrcMetadataId ] );
        if( spNewMetadata == nullptr )
        {
            VMF_EXCEPTION(InternalErrorException, "Unexpected exception!" );
        }

        return spNewMetadata;
    }

    // Make a deep copy, add to the new stream, and add to the map
    std::shared_ptr< Metadata > spNewMetadata( new Metadata( *spMetadata ));
    if( !spNewMetadata->shiftFrameIndex( nTarFrameIndex, nSrcFrameIndex, nNumOfFrames ))
    {
        return nullptr;
    }

    auto nNewMetadataId = this->add( spNewMetadata );
    mapIds[ nSrcMetadataId ] = nNewMetadataId;

    // Wire to the correct description
    auto spNewSchema = this->getSchema( spMetadata->getSchemaName() );
    auto spNewDescriptor = spNewSchema == nullptr ? nullptr : spNewSchema->findMetadataDesc( spMetadata->getName() );
    if( spNewDescriptor == nullptr )
    {
        VMF_EXCEPTION(InternalErrorException, "Metadata schema or description was not found!" );
    }
    spNewMetadata->setDescriptor( spNewDescriptor );

    // Import all references recursively
    spNewMetadata->removeAllReferences();
    auto vReferences = spMetadata->getAllReferences();
    std::for_each( vReferences.begin(), vReferences.end(), [&]( Reference& reference )
    {
        // Import the reference to the new stream
        std::shared_ptr<Metadata> md = reference.getReferenceMetadata().lock();
        auto spNewReference = import( srcStream, md, mapIds, nTarFrameIndex, nSrcFrameIndex, nNumOfFrames );

        // Add as reference
        if( spNewReference != nullptr )
            spNewMetadata->addReference( spNewReference );
    });

    return spNewMetadata;
}
Ejemplo n.º 3
0
void XMPMetadataSource::loadMetadata(const MetaString& pathToCurrentMetadata, const shared_ptr<MetadataDesc>& description, MetadataStream& stream)
{
    IdType id;
    loadMetadataId(pathToCurrentMetadata, id);

    shared_ptr<Metadata> thisMetadata = stream.getById(id);
    if (thisMetadata)
    {
        // already loaded
        return;
    }

    long long frameIndex;
    loadMetadataFrameIndex(pathToCurrentMetadata, frameIndex);

    long long numOfFrames;
    loadMetadataNumOfFrames(pathToCurrentMetadata, numOfFrames);

    long long timestamp;
    loadMetadataTime(pathToCurrentMetadata, timestamp);

    long long duration;
    loadMetadataDuration(pathToCurrentMetadata, duration);

    shared_ptr<MetadataAccessor> metadataAccessor(new MetadataAccessor(description));

    metadataAccessor->setFrameIndex(frameIndex, numOfFrames);
    metadataAccessor->setTimestamp(timestamp, duration);
    metadataAccessor->setId(id);
    MetaString fieldsPath;
    SXMPUtils::ComposeStructFieldPath(VMF_NS, pathToCurrentMetadata.c_str(), VMF_NS, METADATA_FIELDS, &fieldsPath);

    shared_ptr<MetadataSchema> thisSchemaDesc = stream.getSchema(description->getSchemaName());
    shared_ptr<MetadataDesc> thisPropertyDesc = thisSchemaDesc->findMetadataDesc(description->getMetadataName());
    SXMPIterator fieldsIterator(*xmp, VMF_NS, fieldsPath.c_str(), kXMP_IterJustChildren);
    MetaString currentFieldPath;
    while(fieldsIterator.Next(NULL, &currentFieldPath))
    {
        loadField(currentFieldPath, metadataAccessor, thisPropertyDesc);
    }

    MetadataStreamAccessor* streamAccessor = (MetadataStreamAccessor*) &stream;
    streamAccessor->internalAdd(metadataAccessor);

    // Load refs only after adding to steam to stop recursive loading when there are circular references
    MetaString pathToRefs;
    SXMPUtils::ComposeStructFieldPath(VMF_NS, pathToCurrentMetadata.c_str(), VMF_NS, METADATA_REFERENCES, &pathToRefs);
    SXMPIterator refsIterator(*xmp, VMF_NS, pathToRefs.c_str(), kXMP_IterJustChildren);
    MetaString currentRefPath;
    while(refsIterator.Next(NULL, &currentRefPath))
    {
        loadReference(currentRefPath, metadataAccessor, stream);
    }

}