VRS
A file format for sensor data.
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Static Public Member Functions | Protected Member Functions | Friends | List of all members
vrs::Recordable Class Referenceabstract

Class to override to implement a record producing device, or virtual device. More...

#include <Recordable.h>

Inheritance diagram for vrs::Recordable:
vrs_sample_apps::AudioStream vrs_sample_apps::ImageStream vrs_sample_apps::MotionStream vrs_sample_code::MyCameraRecordable vrs_sample_code::RecordableDemo

Public Types

using CreateRecordDelegate = std::function< const Record *(StreamId streamId, double timestamp, Record::Type recordType, uint32_t recordFormatVersion, const DataSource &data)>
 

Public Member Functions

string getRecordableName () const
 
RecordableTypeId getRecordableTypeId () const
 
uint16_t getRecordableInstanceId () const
 
StreamId getStreamId () const
 
void setRecordableIsActive (bool isActive)
 
bool isRecordableActive () const
 
void setCompression (CompressionPreset preset)
 
bool addRecordFormat (Record::Type recordType, uint32_t formatVersion, const RecordFormat &format, const vector< const DataLayout * > &layouts={})
 
virtual const RecordcreateConfigurationRecord ()=0
 
virtual const RecordcreateStateRecord ()=0
 
void setCreateRecordDelegate (CreateRecordDelegate delegate)
 
void setTag (const string &tagName, const string &tagValue)
 
void addTags (const map< string, string > &newTags)
 
void addTags (const StreamTags &tags)
 
const map< string, string > & getTags () const
 
const StreamTagsgetStreamTags () const
 
const string & getSerialNumber () const
 
RecordManagergetRecordManager ()
 

Static Public Member Functions

static const string & getOriginalNameTagName ()
 
static const string & getFlavorTagName ()
 
static const string & getSerialNumberTagName ()
 Get the name of the VRS tag used to store the stream's serial number.
 
static void resetNewInstanceIds ()
 

Protected Member Functions

 Recordable (RecordableTypeId typeId, const string &flavor={})
 
const RecordcreateRecord (double timestampSec, Record::Type recordType, uint32_t formatVersion, const DataSource &data=DataSource())
 
const RecordcreateUncompressedRecord (double timestampSec, Record::Type recordType, uint32_t formatVersion, const DataSource &data, std::unique_ptr< DirectWriteRecordData > &&directWriteRecordData)
 
map< string, string > & getVRSTags ()
 When direct edits of VRS tags is convenient (record filters)
 

Friends

class RecordFileWriter
 

Detailed Description

Class to override to implement a record producing device, or virtual device.

Recordables are meant to be attached to a single RecordFileWriter, that will write its records. Each instance maps one-to-one with a RecordFileWriter's record stream.

Member Typedef Documentation

◆ CreateRecordDelegate

using vrs::Recordable::CreateRecordDelegate = std::function<const Record*( StreamId streamId, double timestamp, Record::Type recordType, uint32_t recordFormatVersion, const DataSource& data)>

Record creation delegate function, to change the record creation behavior without having to override the class. Note that it is valid to deny a record creation request by simply returning a nullptr.

Constructor & Destructor Documentation

◆ Recordable()

vrs::Recordable::Recordable ( RecordableTypeId  typeId,
const string &  flavor = {} 
)
explicitprotected

A recordable has a fixed recordable type id, set at construction and immutable. The instance id is generated by VRS and not user controlled.

See also
StreamId
Parameters
typeIdan id telling which type of stream this is.
flavora flavor required when using << recordable class >> type ids. Note: you may always provide a flavor, but you are required to with << recordable class> ids.

Member Function Documentation

◆ addRecordFormat()

bool vrs::Recordable::addRecordFormat ( Record::Type  recordType,
uint32_t  formatVersion,
const RecordFormat format,
const vector< const DataLayout * > &  layouts = {} 
)

To manage the records of this recordable with RecordFormat, define a RecordFormat for each type of record. It is possible for the same recordable to produce multiple type of records of the same type, using a different formatVersion for each. For each, a different RecordFormat must be defined.

Attention! when you provide a RecordFormat for a record type & formatVersion, all of the streams' records of that type & formatVersion must comply with that RecordFormat.

Parameters
recordTypeThe Record::Type to define.
formatVersionThe format version to define.
formatThe RecordFormat for the records of the type and format version.
layoutsA vector of pointers to DataLayouts and nullptr. For each DataLayout content block of the RecordFormat, a pointer to a DataLayout must be provided for the matching index.
Returns
True if the RecordFormat and the layouts match as expected. Otherwise, false is returned and errors will be logged to help debug the problem.

◆ addTags() [1/2]

void vrs::Recordable::addTags ( const map< string, string > &  newTags)

Add file tags in bulk.

Parameters
newTagsA map of string name/value pairs.

◆ addTags() [2/2]

void vrs::Recordable::addTags ( const StreamTags tags)

Add many tags at once, both internal & user tags. This method is meant for record stream copy operations, when all the tags of a read record stream need to be copied to a recordable capturing the copy of the stream.

Parameters
tagsUser and VRS tags to set, probably coming from RecordFileReader::getTag(id).

◆ createConfigurationRecord()

virtual const Record * vrs::Recordable::createConfigurationRecord ( )
pure virtual

Configuration records describe how the device recorded is configured/setup. The configuration of a recordable is probably not changed by data flowing through. A framerate, a resolution, are probably part of the configuration. An exposure setting as well, unless it is automatically adjusted as data flows through. The RecordFileWriter will call this method to make sure a configuration record is captured, when a record file is created asynchronously.

Implemented in vrs_sample_apps::ImageStream, vrs_sample_apps::AudioStream, vrs_sample_apps::MotionStream, vrs_sample_code::RecordableDemo, and vrs_sample_code::MyCameraRecordable.

◆ createRecord()

const Record * vrs::Recordable::createRecord ( double  timestampSec,
Record::Type  recordType,
uint32_t  formatVersion,
const DataSource data = DataSource() 
)
inlineprotected

Create a new record for this recordable. That's the preferred API to create records.

When the call returns:

  • a record has been created and is fully owned and managed by the recordable's RecordManager, despite returning a pointer to it.
  • the DataSource referenced by data has fully been copied in the record, so that the caller is immediately entirely free to reuse or delete the source data as desired.
Parameters
timestampSecTimestamp of the record. All the records of all the recordables attached to the same RecordFileWriter must have timestamps in the same time domain, or they won't be managed & sorted in a sensible way. Respecting this requirement is essential, as records will be ordered on disk and played back sorted by their timestamp. Timestamps are a count of seconds since some arbitrary point in time, EPOCH or not (usually).
recordTypeThe type of the record.
formatVersionEach record specifies how it encodes its data using a formatVersion. This format version may reference a RecordFormat definition that has been provided using RecordFormat::addRecordFormat() (new/better API), or reference a data format managed manually by the user of the API (early API, before RecordFormat & DataLayout). The version number only need to be unique for this device and record type, but needs to be carefully managed over time, or you won't be able to interpret files created in the past.
dataA DataSource that points to the record's actual data payload.
Returns
record: A pointer to the created record, that's owned & managed by the recordable's RecordManager. Client code probably shouldn't do much with that pointer. Attention! This pointer may be null, in particular when a delegate intercepts the request!

◆ createStateRecord()

virtual const Record * vrs::Recordable::createStateRecord ( )
pure virtual

State records describe the internal state of the device, if it's stateful. It is probably the result of previous calculation/processing of data.

State records should not to be confused with the configuration of the device. A position tracking algorithm probably has a state: the last position it determined, which will be used to calculate the next state when the next data come in. State data typically changes as data flows, according to that data. A camera probably has no state, but probably has a configuration. The RecordFileWriter will call this method to make sure a configuration record is captured, when a record file is created asynchronously.

Implemented in vrs_sample_apps::ImageStream, vrs_sample_apps::AudioStream, vrs_sample_apps::MotionStream, vrs_sample_code::RecordableDemo, and vrs_sample_code::MyCameraRecordable.

◆ createUncompressedRecord()

const Record * vrs::Recordable::createUncompressedRecord ( double  timestampSec,
Record::Type  recordType,
uint32_t  formatVersion,
const DataSource data,
std::unique_ptr< DirectWriteRecordData > &&  directWriteRecordData 
)
inlineprotected

Create a record which last part will be written directly to the file when the record is written to disk, therefore bypassing the record creation memory copy for that part. This API is designed for high bandwidth live recording situations, when we must avoid the record creation's memory copy to achieve the required performance.

Note: using a DirectWriteRecordData object prevents that record from being compressed by VRS, since that data is written directly to the file, hence the name of the API.

When the call returns:

  • a record has been created and is fully owned and managed by the recordable's RecordManager, despite returning a pointer to it.
  • the data referenced by the DataSource has been fully copied in the record's internal buffer, so that the caller can free or modify that source data immediately. You probably want to use that DataSource to save the DataLayout part of the record.
  • the directWriteRecordData object will be owned by the record until it can be used to write its data directly at the end of the record, and deleted only then. Use that object to write the heavy payload of your record, such as the raw image data. directWriteRecordData's data MUST live long enough for the record to be written.
    Parameters
    timestampTimestamp of the record, in seconds.
    typeType of the record.
    formatVersionVersion number of the format of the record, so that when the record is read, the data can be interpreted appropriately.
    dataA DataSource that points to the payload to copy in the record immediately.
    directWriteRecordDatadata to write directly in the file at the end of the record.
    Returns
    A pointer to the record created.

◆ getFlavorTagName()

static const string & vrs::Recordable::getFlavorTagName ( )
inlinestatic

Get the name of the VRS tag used to store recordable flavors.

◆ getOriginalNameTagName()

static const string & vrs::Recordable::getOriginalNameTagName ( )
inlinestatic

Get the name of the VRS tag used to store the original name of the recordable.

◆ getRecordableInstanceId()

uint16_t vrs::Recordable::getRecordableInstanceId ( ) const
inline

Get the unique instance id for this particular recordable.

Returns
The object's instance id.

◆ getRecordableName()

string vrs::Recordable::getRecordableName ( ) const
inline

Get a readable name for the recordable, based on its StreamId.

Returns
The instance's StreamId name.

◆ getRecordableTypeId()

RecordableTypeId vrs::Recordable::getRecordableTypeId ( ) const
inline

Get this instance's recordable type. Can never change for this instance.

Returns
The instance's RecordableTypeId.

◆ getRecordManager()

RecordManager & vrs::Recordable::getRecordManager ( )
inline

Get the recordable's RecordManager. Not meant for client code use.

◆ getSerialNumber()

const string & vrs::Recordable::getSerialNumber ( ) const
inline

Get the stream's unique serial number generated on stream creation. That serial number is universally unique and it will be preserved during file copies, file processing, and other manipulations that preserve stream tags, whereas the stream's streamID may change. Note that VRS internal tags might be overwritten, in particular during file copy operations, so this serial number might be intentionally replaced (by design).

◆ getStreamId()

StreamId vrs::Recordable::getStreamId ( ) const
inline

Get the recordable's StreamId.

Returns
The recordable's StreamId.

◆ getStreamTags()

const StreamTags & vrs::Recordable::getStreamTags ( ) const
inline

Get all the tags at once, both internal & user tags.

Returns
All the user and VRS tags.

◆ getTags()

const map< string, string > & vrs::Recordable::getTags ( ) const
inline

Get the user tags, all at once.

Returns
Map of tag-name/tag-value pairs.

◆ isRecordableActive()

bool vrs::Recordable::isRecordableActive ( ) const
inline

Tell if the recordable is active for recording.

Returns
True if records will be recorded the next time the record file writer will look for records to write.

◆ resetNewInstanceIds()

void vrs::Recordable::resetNewInstanceIds ( )
static

Recordable instance ids are automatically assigned when Recordable objects are created. This guarantees that each Recordable gets a unique ID. WARNING! If your code relies on specific instance IDs, your design is weak, and you are setting up your project for a world of pain in the future. Use flavors and tag pairs to identify your streams instead. However, when many files are generated successively, it can lead to high instance id values, which can be confusing, and even problematic for unit tests. Use this API to reset the instance counters for each device type, so that the next devices will get an instance id of 1. ATTENTION! if you call this API at the wrong time, you can end up with multiple devices with the same id, and end up in a messy situation. Avoid this API if you can!

◆ setCompression()

void vrs::Recordable::setCompression ( CompressionPreset  preset)

Override default compression preset for this recordable.

Parameters
presetThe compression preset to use when writing the next records.

◆ setCreateRecordDelegate()

void vrs::Recordable::setCreateRecordDelegate ( CreateRecordDelegate  delegate)
inline

Record creation requests may be intercepted by setting a CreationRecordDelegate. Using this method, as opposed to making createRecord virtual, can allow interception of record creation requests, for instance, if you want to redirect record creations to another process, without having to change the class inheritance hierarchy. Note that you normally do not need to do this.

Parameters
delegatean external function that will handed data when a record needs to be created. You can unset the delegate by using a empty function.

◆ setRecordableIsActive()

void vrs::Recordable::setRecordableIsActive ( bool  isActive)
inline

Activate a recordable to enable recording. Must be enabled for pre-record buffering. Recording a device's records can be enabled and disabled on the fly during recording. Recordables can't be added or removed from a RecordFileWriter while a file is being written, but recordables can be activated and deactivated instead.

◆ setTag()

void vrs::Recordable::setTag ( const string &  tagName,
const string &  tagValue 
)

Set tags for each Recordable, so that you reconfigure the system when reading. Note: tags are written when the file is created, so you need to create them early enough.

Parameters
tagNameThe name of the tag.
tagValueThe value of the tag.

The documentation for this class was generated from the following files: