Skip to content

Commit

Permalink
Adds an experimental VideoSourceMetadata analyser.
Browse files Browse the repository at this point in the history
Signed-off-by: Ralph Gasser <[email protected]>
  • Loading branch information
ppanopticon committed Dec 21, 2023
1 parent fd78174 commit 5991e5c
Show file tree
Hide file tree
Showing 18 changed files with 355 additions and 139 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package org.vitrivr.engine.core.features.metadata.source.file

import io.github.oshai.kotlinlogging.KLogger
import io.github.oshai.kotlinlogging.KotlinLogging
import org.vitrivr.engine.core.context.IndexContext
import org.vitrivr.engine.core.context.QueryContext
import org.vitrivr.engine.core.model.content.element.ContentElement
import org.vitrivr.engine.core.model.descriptor.struct.metadata.source.FileSourceMetadataDescriptor
import org.vitrivr.engine.core.model.metamodel.Analyser
import org.vitrivr.engine.core.model.metamodel.Schema
import org.vitrivr.engine.core.model.retrievable.Retrievable
import org.vitrivr.engine.core.operators.Operator
import org.vitrivr.engine.core.operators.retrieve.Retriever
import java.util.*

private val logger: KLogger = KotlinLogging.logger {}

/**
* Implementation of the [FileSourceMetadata] [Analyser], which derives metadata information from file-based retrievables
*
* @author Ralph Gasser
* @version 1.0.0
*/
class FileSourceMetadata : Analyser<ContentElement<*>, FileSourceMetadataDescriptor> {
override val contentClasses = setOf(ContentElement::class)
override val descriptorClass = FileSourceMetadataDescriptor::class

/**
* Generates a prototypical [FileSourceMetadataDescriptor] for this [FileSourceMetadata].
*
* @return [FileSourceMetadataDescriptor]
*/
override fun prototype() = FileSourceMetadataDescriptor(UUID.randomUUID(), UUID.randomUUID(), "", 0, true)

/**
* Generates and returns a new [FileSourceMetadataExtractor] for the provided [Schema.Field].
*
* @param field The [Schema.Field] for which to create the [FileSourceMetadataExtractor].
* @param input The input [Operator]
* @param context The [IndexContext]
* @param persisting Whether the resulting [FileSourceMetadataDescriptor]s should be persisted.
*
* @return [FileSourceMetadataExtractor]
*/
override fun newExtractor(field: Schema.Field<ContentElement<*>, FileSourceMetadataDescriptor>, input: Operator<Retrievable>, context: IndexContext, persisting: Boolean, parameters: Map<String, Any>): FileSourceMetadataExtractor {
require(field.analyser == this) { "Field type is incompatible with analyser. This is a programmer's error!" }
logger.debug { "Creating new FileMetadataExtractor for field '${field.fieldName}' with parameters $parameters." }
return FileSourceMetadataExtractor(input, field, persisting)
}

/**
* Generates and returns a new [FileSourceMetadataRetriever] for the provided [Schema.Field].
*
* @param field The [Schema.Field] for which to create the [FileSourceMetadataRetriever].
* @param content The [List] of [ContentElement] to create [FileSourceMetadataRetriever] for. This is usually empty.
* @param context The [QueryContext]
*
* @return [FileSourceMetadataRetriever]
*/
override fun newRetrieverForContent(field: Schema.Field<ContentElement<*>, FileSourceMetadataDescriptor>, content: Collection<ContentElement<*>>, context: QueryContext): FileSourceMetadataRetriever {
require(field.analyser == this) { "Field type is incompatible with analyser. This is a programmer's error!" }
return FileSourceMetadataRetriever(field, context)
}

/**
* Generates and returns a new [FileSourceMetadataRetriever] for the provided [Schema.Field].
*
* @param field The [Schema.Field] for which to create the [FileSourceMetadataRetriever].
* @param descriptors The [List] of [FileSourceMetadataDescriptor] to create [FileSourceMetadataRetriever] for. This is usually empty.
* @param context The [QueryContext]
*
* @return [FileSourceMetadataRetriever]
*/
override fun newRetrieverForDescriptors(
field: Schema.Field<ContentElement<*>, FileSourceMetadataDescriptor>,
descriptors: Collection<FileSourceMetadataDescriptor>,
context: QueryContext
): Retriever<ContentElement<*>, FileSourceMetadataDescriptor> {
require(field.analyser == this) { "Field type is incompatible with analyser. This is a programmer's error!" }
return FileSourceMetadataRetriever(field, context)
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package org.vitrivr.engine.core.features.metadata.file
package org.vitrivr.engine.core.features.metadata.source.file

import org.vitrivr.engine.core.features.AbstractExtractor
import org.vitrivr.engine.core.model.content.element.ContentElement
import org.vitrivr.engine.core.model.descriptor.Descriptor
import org.vitrivr.engine.core.model.descriptor.struct.metadata.FileMetadataDescriptor
import org.vitrivr.engine.core.model.descriptor.struct.metadata.source.FileSourceMetadataDescriptor
import org.vitrivr.engine.core.model.metamodel.Schema
import org.vitrivr.engine.core.model.retrievable.Ingested
import org.vitrivr.engine.core.model.retrievable.Retrievable
Expand All @@ -16,20 +16,20 @@ import java.util.*
import kotlin.io.path.absolutePathString

/**
* An [Extractor] that extracts [FileMetadataDescriptor]s from [Ingested] objects.
* An [Extractor] that extracts [FileSourceMetadataDescriptor]s from [Ingested] objects.
*
* @author Ralph Gasser
* @version 1.0.0
*/
class FileMetadataExtractor(
class FileSourceMetadataExtractor(
input: Operator<Retrievable>,
field: Schema.Field<ContentElement<*>, FileMetadataDescriptor>,
field: Schema.Field<ContentElement<*>, FileSourceMetadataDescriptor>,
persisting: Boolean = true
) : AbstractExtractor<ContentElement<*>, FileMetadataDescriptor>(input, field, persisting, bufferSize = 1) {
) : AbstractExtractor<ContentElement<*>, FileSourceMetadataDescriptor>(input, field, persisting, bufferSize = 1) {
/**
* Internal method to check, if [Retrievable] matches this [Extractor] and should thus be processed.
*
* [FileMetadataExtractor] implementation only works with [RetrievableWithSource] that contain a [FileSource].
* [FileSourceMetadataExtractor] implementation only works with [RetrievableWithSource] that contain a [FileSource].
*
* @param retrievable The [Retrievable] to check.
* @return True on match, false otherwise,
Expand All @@ -43,11 +43,11 @@ class FileMetadataExtractor(
* @param retrievable The [Retrievable] to process.
* @return List of resulting [Descriptor]s.
*/
override fun extract(retrievable: Retrievable): List<FileMetadataDescriptor> {
override fun extract(retrievable: Retrievable): List<FileSourceMetadataDescriptor> {
check(retrievable is RetrievableWithSource) { "Incoming retrievable is not a retrievable with source. This is a programmer's error!" }
check(retrievable.source is FileSource) { "Incoming retrievable is not a retrievable with file source. This is a programmer's error!" }
return listOf(
FileMetadataDescriptor(
FileSourceMetadataDescriptor(
id = UUID.randomUUID(),
retrievableId = retrievable.id,
path = (retrievable.source as FileSource).path.absolutePathString(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
package org.vitrivr.engine.core.features.metadata.file
package org.vitrivr.engine.core.features.metadata.source.file

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import org.vitrivr.engine.core.context.QueryContext
import org.vitrivr.engine.core.model.content.element.ContentElement
import org.vitrivr.engine.core.model.descriptor.struct.metadata.FileMetadataDescriptor
import org.vitrivr.engine.core.model.descriptor.struct.metadata.source.FileSourceMetadataDescriptor
import org.vitrivr.engine.core.model.metamodel.Schema
import org.vitrivr.engine.core.model.retrievable.Retrieved
import org.vitrivr.engine.core.operators.retrieve.Retriever

/**
* A [Retriever] that performs lookup on [FileMetadataDescriptor]s.
* A [Retriever] that performs lookup on [FileSourceMetadataDescriptor]s.
*
* @author Ralph Gasser
* @version 1.0.0
*/
class FileMetadataRetriever(override val field: Schema.Field<ContentElement<*>, FileMetadataDescriptor>, private val context: QueryContext) : Retriever<ContentElement<*>, FileMetadataDescriptor> {
class FileSourceMetadataRetriever(override val field: Schema.Field<ContentElement<*>, FileSourceMetadataDescriptor>, private val context: QueryContext) : Retriever<ContentElement<*>, FileSourceMetadataDescriptor> {
override fun toFlow(scope: CoroutineScope): Flow<Retrieved> {
TODO("Not yet implemented")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package org.vitrivr.engine.core.features.metadata.source.video

import org.vitrivr.engine.core.context.IndexContext
import org.vitrivr.engine.core.context.QueryContext
import org.vitrivr.engine.core.features.metadata.source.file.FileSourceMetadata
import org.vitrivr.engine.core.features.metadata.source.file.FileSourceMetadataExtractor
import org.vitrivr.engine.core.features.metadata.source.file.FileSourceMetadataRetriever
import org.vitrivr.engine.core.model.content.element.ContentElement
import org.vitrivr.engine.core.model.descriptor.struct.metadata.source.FileSourceMetadataDescriptor
import org.vitrivr.engine.core.model.descriptor.struct.metadata.source.VideoSourceMetadataDescriptor
import org.vitrivr.engine.core.model.metamodel.Analyser
import org.vitrivr.engine.core.model.metamodel.Schema
import org.vitrivr.engine.core.model.retrievable.Retrievable
import org.vitrivr.engine.core.operators.Operator
import org.vitrivr.engine.core.operators.retrieve.Retriever
import java.util.*

/**
* Implementation of the [VideoSourceMetadata] [Analyser], which derives metadata information from [Retr]
*
* @author Ralph Gasser
* @version 1.0.0
*/
class VideoSourceMetadata : Analyser<ContentElement<*>, VideoSourceMetadataDescriptor> {
override val contentClasses = setOf(ContentElement::class)
override val descriptorClass = VideoSourceMetadataDescriptor::class

/**
* Generates a prototypical [FileSourceMetadataDescriptor] for this [FileSourceMetadata].
*
* @return [FileSourceMetadataDescriptor]
*/
override fun prototype() = VideoSourceMetadataDescriptor.PROTOTYPE

/**
* Generates and returns a new [FileSourceMetadataExtractor] for the provided [Schema.Field].
*
* @param field The [Schema.Field] for which to create the [FileSourceMetadataExtractor].
* @param input The input [Operator]
* @param context The [IndexContext]
* @param persisting Whether the resulting [FileSourceMetadataDescriptor]s should be persisted.
*
* @return [FileSourceMetadataExtractor]
*/
override fun newExtractor(field: Schema.Field<ContentElement<*>, VideoSourceMetadataDescriptor>, input: Operator<Retrievable>, context: IndexContext, persisting: Boolean, parameters: Map<String, Any>): VideoSourceMetadataExtractor {
require(field.analyser == this) { "Field type is incompatible with analyser. This is a programmer's error!" }
return VideoSourceMetadataExtractor(input, field, persisting)
}

/**
* Generates and returns a new [FileSourceMetadataRetriever] for the provided [Schema.Field].
*
* @param field The [Schema.Field] for which to create the [FileSourceMetadataRetriever].
* @param content The [List] of [ContentElement] to create [FileSourceMetadataRetriever] for. This is usually empty.
* @param context The [QueryContext]
*
* @return [FileSourceMetadataRetriever]
*/
override fun newRetrieverForContent(field: Schema.Field<ContentElement<*>, VideoSourceMetadataDescriptor>, content: Collection<ContentElement<*>>, context: QueryContext): VideoSourceMetadataRetriever {
require(field.analyser == this) { "Field type is incompatible with analyser. This is a programmer's error!" }
return VideoSourceMetadataRetriever(field, context)
}

/**
* Generates and returns a new [FileSourceMetadataRetriever] for the provided [Schema.Field].
*
* @param field The [Schema.Field] for which to create the [FileSourceMetadataRetriever].
* @param descriptors The [List] of [FileSourceMetadataDescriptor] to create [FileSourceMetadataRetriever] for. This is usually empty.
* @param context The [QueryContext]
*
* @return [FileSourceMetadataRetriever]
*/
override fun newRetrieverForDescriptors(
field: Schema.Field<ContentElement<*>, VideoSourceMetadataDescriptor>,
descriptors: Collection<VideoSourceMetadataDescriptor>,
context: QueryContext
): Retriever<ContentElement<*>, VideoSourceMetadataDescriptor> {
require(field.analyser == this) { "Field type is incompatible with analyser. This is a programmer's error!" }
return VideoSourceMetadataRetriever(field, context)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package org.vitrivr.engine.core.features.metadata.source.video

import org.vitrivr.engine.core.features.AbstractExtractor
import org.vitrivr.engine.core.features.metadata.source.file.FileSourceMetadataExtractor
import org.vitrivr.engine.core.model.content.element.ContentElement
import org.vitrivr.engine.core.model.descriptor.Descriptor
import org.vitrivr.engine.core.model.descriptor.struct.metadata.source.VideoSourceMetadataDescriptor
import org.vitrivr.engine.core.model.metamodel.Schema
import org.vitrivr.engine.core.model.retrievable.Retrievable
import org.vitrivr.engine.core.model.retrievable.decorators.RetrievableWithSource
import org.vitrivr.engine.core.operators.Operator
import org.vitrivr.engine.core.operators.ingest.Extractor
import org.vitrivr.engine.core.source.MediaType
import org.vitrivr.engine.core.source.file.FileSource
import java.util.*

/**
*
* @author Ralph Gasser
* @version 1.0.0
*/
class VideoSourceMetadataExtractor(
input: Operator<Retrievable>,
field: Schema.Field<ContentElement<*>, VideoSourceMetadataDescriptor>,
persisting: Boolean = true
) : AbstractExtractor<ContentElement<*>, VideoSourceMetadataDescriptor>(input, field, persisting, bufferSize = 1) {
/**
* Internal method to check, if [Retrievable] matches this [Extractor] and should thus be processed.
*
* [FileSourceMetadataExtractor] implementation only works with [RetrievableWithSource] that contain a [FileSource].
*
* @param retrievable The [Retrievable] to check.
* @return True on match, false otherwise,
*/
override fun matches(retrievable: Retrievable): Boolean =
retrievable is RetrievableWithSource && retrievable.source.type == MediaType.VIDEO

/**
* Internal method to perform extraction on [Retrievable].
**
* @param retrievable The [Retrievable] to process.
* @return List of resulting [Descriptor]s.
*/
override fun extract(retrievable: Retrievable): List<VideoSourceMetadataDescriptor> {
check(retrievable is RetrievableWithSource) { "Incoming retrievable is not a retrievable with source. This is a programmer's error!" }
check(retrievable.source.type == MediaType.VIDEO) { "Incoming retrievable is not a retrievable with video source. This is a programmer's error!" }
return listOf(
VideoSourceMetadataDescriptor(
id = UUID.randomUUID(),
retrievableId = retrievable.id,
width = retrievable.source.width() ?: 0,
height = retrievable.source.height() ?: 0,
fps = retrievable.source.fps() ?: 0.0,
channels = retrievable.source.channels() ?: 0,
sampleRate = retrievable.source.sampleRate() ?: 0,
sampleSize = retrievable.source.sampleSize() ?: 0,
transient = !persisting
)
)
}
}
Loading

0 comments on commit 5991e5c

Please sign in to comment.