Skip to content

Commit

Permalink
Add available precharge and rollout info
Browse files Browse the repository at this point in the history
The available precharge is the count of edit units available before the
target position. Available precharge is <= precharge, where precharge is
always <= 0. I.e. there may be more edit units available than strictly
necessary for precharge.

Similar for rollout, where available rollout is the count of edit units
available after the target position.
  • Loading branch information
philipnbbc committed Aug 17, 2023
1 parent 86b3c86 commit 137fc13
Show file tree
Hide file tree
Showing 17 changed files with 334 additions and 0 deletions.
16 changes: 16 additions & 0 deletions apps/mxf2raw/mxf2raw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -812,10 +812,14 @@ static void write_track_info(AppInfoWriter *info_writer, MXFReader *reader, MXFT
const MXFDataTrackInfo *data_info = dynamic_cast<const MXFDataTrackInfo*>(track_info);

int16_t precharge = 0;
int64_t available_precharge = 0;
int16_t rollout = 0;
int64_t available_rollout = 0;
if (reader->IsComplete() && track_reader->GetDuration() > 0) {
precharge = track_reader->GetPrecharge(0, true);
available_precharge = track_reader->GetAvailablePrecharge(0);
rollout = track_reader->GetRollout(track_reader->GetDuration() - 1, true);
available_rollout = track_reader->GetAvailableRollout(track_reader->GetDuration() - 1);
}

info_writer->WriteEnumStringItem("essence_kind", ESSENCE_KIND_EINFO, track_info->data_def);
Expand All @@ -831,8 +835,12 @@ static void write_track_info(AppInfoWriter *info_writer, MXFReader *reader, MXFT
}
if (precharge != 0)
info_writer->WriteIntegerItem("precharge", precharge);
if (available_precharge != 0)
info_writer->WriteIntegerItem("available_precharge", available_precharge);
if (rollout != 0)
info_writer->WriteIntegerItem("rollout", rollout);
if (available_rollout != 0)
info_writer->WriteIntegerItem("available_rollout", available_rollout);
if (checksums) {
size_t i;
for (i = 0; i < checksums->size(); i++) {
Expand Down Expand Up @@ -1032,10 +1040,14 @@ static void write_clip_info(AppInfoWriter *info_writer, MXFReader *reader,
bool have_track_crc32_data = (track_crc32_data.size() == reader->GetNumTrackReaders());

int16_t max_precharge = 0;
int64_t max_available_precharge = 0;
int16_t max_rollout = 0;
int64_t max_available_rollout = 0;
if (reader->IsComplete() && reader->GetDuration() > 0) {
max_precharge = reader->GetMaxPrecharge(0, false);
max_available_precharge = reader->GetMaxAvailablePrecharge(0);
max_rollout = reader->GetMaxRollout(reader->GetDuration() - 1, false);
max_available_rollout = reader->GetMaxAvailableRollout(reader->GetDuration() - 1);
}

string clip_name = reader->GetMaterialPackageName();
Expand All @@ -1046,8 +1058,12 @@ static void write_clip_info(AppInfoWriter *info_writer, MXFReader *reader,
info_writer->WriteDurationItem("duration", reader->GetDuration(), edit_rate);
if (max_precharge != 0)
info_writer->WriteIntegerItem("max_precharge", max_precharge);
if (max_available_precharge != 0)
info_writer->WriteIntegerItem("max_available_precharge", max_available_precharge);
if (max_rollout != 0)
info_writer->WriteIntegerItem("max_rollout", max_rollout);
if (max_available_rollout != 0)
info_writer->WriteIntegerItem("max_available_rollout", max_available_rollout);

// Write Primary Package if it's a single (main) file only
MXFFileReader *file_reader = dynamic_cast<MXFFileReader*>(reader);
Expand Down
4 changes: 4 additions & 0 deletions include/bmx/mxf_reader/MXFFileReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,9 @@ class MXFFileReader : public MXFReader
virtual int64_t GetPosition() const;

virtual int16_t GetMaxPrecharge(int64_t position, bool limit_to_available) const;
virtual int64_t GetMaxAvailablePrecharge(int64_t position) const;
virtual int16_t GetMaxRollout(int64_t position, bool limit_to_available) const;
virtual int64_t GetMaxAvailableRollout(int64_t position) const;

public:
virtual int64_t GetFixedLeadFillerOffset() const;
Expand Down Expand Up @@ -207,7 +209,9 @@ class MXFFileReader : public MXFReader

bool GetInternalIndexEntry(MXFIndexEntryExt *entry, int64_t position) const;
int16_t GetInternalPrecharge(int64_t position, bool limit_to_available) const;
int64_t GetInternalAvailablePrecharge(int64_t position) const;
int16_t GetInternalRollout(int64_t position, bool limit_to_available) const;
int64_t GetInternalAvailableRollout(int64_t position) const;
void GetInternalAvailableReadLimits(int64_t *start_position, int64_t *duration) const;

bool HaveInterFrameEncodingTrack() const;
Expand Down
2 changes: 2 additions & 0 deletions include/bmx/mxf_reader/MXFFileTrackReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ class MXFFileTrackReader : public MXFTrackReader
virtual bool GetIndexEntry(MXFIndexEntryExt *entry, int64_t position = CURRENT_POSITION_VALUE) const;

virtual int16_t GetPrecharge(int64_t position, bool limit_to_available) const;
virtual int64_t GetAvailablePrecharge(int64_t position) const;
virtual int16_t GetRollout(int64_t position, bool limit_to_available) const;
virtual int64_t GetAvailableRollout(int64_t position) const;

virtual MXFTrackInfo* GetTrackInfo() const { return mTrackInfo; }
virtual mxfpp::FileDescriptor* GetFileDescriptor() const { return mFileDescriptor; }
Expand Down
2 changes: 2 additions & 0 deletions include/bmx/mxf_reader/MXFGroupReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ class MXFGroupReader : public MXFReader
virtual int64_t GetPosition() const;

virtual int16_t GetMaxPrecharge(int64_t position, bool limit_to_available) const;
virtual int64_t GetMaxAvailablePrecharge(int64_t position) const;
virtual int16_t GetMaxRollout(int64_t position, bool limit_to_available) const;
virtual int64_t GetMaxAvailableRollout(int64_t position) const;

public:
virtual int64_t GetFixedLeadFillerOffset() const;
Expand Down
6 changes: 6 additions & 0 deletions include/bmx/mxf_reader/MXFReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,14 @@ class MXFReader

virtual int64_t GetPosition() const = 0;

// Returns the maximum precharge required for the given position.
virtual int16_t GetMaxPrecharge(int64_t position, bool limit_to_available) const = 0;
// Returns the maximum precharge available before the given position.
virtual int64_t GetMaxAvailablePrecharge(int64_t position) const = 0;
// Returns the maximum rollout required for the given position.
virtual int16_t GetMaxRollout(int64_t position, bool limit_to_available) const = 0;
// Returns the maximum rollout available after the given position.
virtual int64_t GetMaxAvailableRollout(int64_t position) const = 0;

mxfRational GetEditRate() const { return mEditRate; }
int64_t GetDuration() const { return mDuration; }
Expand Down
2 changes: 2 additions & 0 deletions include/bmx/mxf_reader/MXFSequenceReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ class MXFSequenceReader : public MXFReader
virtual int64_t GetPosition() const { return mPosition; }

virtual int16_t GetMaxPrecharge(int64_t position, bool limit_to_available) const;
virtual int64_t GetMaxAvailablePrecharge(int64_t position) const;
virtual int16_t GetMaxRollout(int64_t position, bool limit_to_available) const;
virtual int64_t GetMaxAvailableRollout(int64_t position) const;

public:
virtual int64_t GetFixedLeadFillerOffset() const;
Expand Down
2 changes: 2 additions & 0 deletions include/bmx/mxf_reader/MXFSequenceTrackReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ class MXFSequenceTrackReader : public MXFTrackReader
virtual bool GetIndexEntry(MXFIndexEntryExt *entry, int64_t position = CURRENT_POSITION_VALUE) const;

virtual int16_t GetPrecharge(int64_t position, bool limit_to_available) const;
virtual int64_t GetAvailablePrecharge(int64_t position) const;
virtual int16_t GetRollout(int64_t position, bool limit_to_available) const;
virtual int64_t GetAvailableRollout(int64_t position) const;

virtual MXFTrackInfo* GetTrackInfo() const { return mTrackInfo; }
virtual mxfpp::FileDescriptor* GetFileDescriptor() const { return mFileDescriptor; }
Expand Down
8 changes: 8 additions & 0 deletions include/bmx/mxf_reader/MXFTimedTextTrackReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ class MXFTimedTextTrackReader : public MXFFileTrackReader
mxfpp::FileDescriptor *file_descriptor, mxfpp::SourcePackage *file_source_package);
virtual ~MXFTimedTextTrackReader();

virtual int64_t GetOrigin() const;

virtual int16_t GetPrecharge(int64_t position, bool limit_to_available) const;
virtual int64_t GetAvailablePrecharge(int64_t position) const;
virtual int16_t GetRollout(int64_t position, bool limit_to_available) const;
virtual int64_t GetAvailableRollout(int64_t position) const;

public:
void SetBodySID(uint32_t body_sid);

TimedTextManifest* GetManifest();
Expand Down
6 changes: 6 additions & 0 deletions include/bmx/mxf_reader/MXFTrackReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,14 @@ class MXFTrackReader

virtual bool GetIndexEntry(MXFIndexEntryExt *entry, int64_t position = CURRENT_POSITION_VALUE) const = 0;

// Returns the precharge required for the given position.
virtual int16_t GetPrecharge(int64_t position, bool limit_to_available) const = 0;
// Returns the precharge available before the given position.
virtual int64_t GetAvailablePrecharge(int64_t position) const = 0;
// Returns the rollout required for the given position.
virtual int16_t GetRollout(int64_t position, bool limit_to_available) const = 0;
// Returns the rollout available after the given position.
virtual int64_t GetAvailableRollout(int64_t position) const = 0;

virtual MXFTrackInfo* GetTrackInfo() const = 0;
virtual mxfpp::FileDescriptor* GetFileDescriptor() const = 0;
Expand Down
4 changes: 4 additions & 0 deletions meta/mxf2raw/mxf2raw_info.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,9 @@
<xs:element name="edit_rate" type="rational_type"/>
<xs:element name="duration" type="duration_type"/>
<xs:element name="max_precharge" type="int16_type" minOccurs="0"/>
<xs:element name="max_available_precharge" type="int64_type" minOccurs="0"/>
<xs:element name="max_rollout" type="int16_type" minOccurs="0"/>
<xs:element name="max_available_rollout" type="int64_type" minOccurs="0"/>
<xs:element name="primary_package" type="primary_package_type" minOccurs="0"/>
<xs:element name="start_timecodes" type="start_timecodes_type"/>
<xs:element name="tracks" type="tracks_type"/>
Expand Down Expand Up @@ -265,7 +267,9 @@
<xs:element name="lead_filler_offset" type="position_type" minOccurs="0"/>
<xs:element name="timed_text_offset" type="position_type" minOccurs="0"/>
<xs:element name="precharge" type="int16_type" minOccurs="0"/>
<xs:element name="available_precharge" type="int64_type" minOccurs="0"/>
<xs:element name="rollout" type="int16_type" minOccurs="0"/>
<xs:element name="available_rollout" type="int64_type" minOccurs="0"/>
<xs:element name="checksum" type="checksum_type" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="crc32_check" type="crc32_check_type" minOccurs="0"/>
<xs:element name="packages" type="track_packages_type"/>
Expand Down
100 changes: 100 additions & 0 deletions src/mxf_reader/MXFFileReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,38 @@ int16_t MXFFileReader::GetMaxPrecharge(int64_t position, bool limit_to_available
return precharge < 0 ? (int16_t)precharge : 0;
}

int64_t MXFFileReader::GetMaxAvailablePrecharge(int64_t position) const
{
CHECK_SUPPORT_PC_RO_INFO;

int64_t target_position = position;
if (target_position == CURRENT_POSITION_VALUE)
target_position = GetPosition();

int64_t max_available_precharge = 0;
if (InternalIsEnabled())
max_available_precharge = GetInternalAvailablePrecharge(target_position);

size_t i;
for (i = 0; i < mExternalReaders.size(); i++) {
if (!mExternalReaders[i]->IsEnabled())
continue;

int64_t ext_max_available_precharge = mExternalReaders[i]->GetMaxAvailablePrecharge(
CONVERT_INTERNAL_POS(target_position));
if (ext_max_available_precharge != 0) {
if (mExternalReaders[i]->GetEditRate() != mEditRate) {
log_warn("Currently only support available precharge in external reader if "
"external reader edit rate equals group edit rate");
} else if (ext_max_available_precharge < max_available_precharge) {
max_available_precharge = ext_max_available_precharge;
}
}
}

return max_available_precharge;
}

int16_t MXFFileReader::GetMaxRollout(int64_t position, bool limit_to_available) const
{
CHECK_SUPPORT_PC_RO_INFO;
Expand Down Expand Up @@ -842,6 +874,38 @@ int16_t MXFFileReader::GetMaxRollout(int64_t position, bool limit_to_available)
return rollout > 0 ? (int16_t)rollout : 0;
}

int64_t MXFFileReader::GetMaxAvailableRollout(int64_t position) const
{
CHECK_SUPPORT_PC_RO_INFO;

int64_t target_position = position;
if (target_position == CURRENT_POSITION_VALUE)
target_position = GetPosition();

int64_t max_available_rollout = 0;
if (InternalIsEnabled())
max_available_rollout = GetInternalAvailableRollout(target_position);

size_t i;
for (i = 0; i < mExternalReaders.size(); i++) {
if (!mExternalReaders[i]->IsEnabled())
continue;

int16_t ext_max_available_rollout = mExternalReaders[i]->GetMaxAvailableRollout(
CONVERT_INTERNAL_POS(target_position + 1) - 1);
if (ext_max_available_rollout != 0) {
if (mExternalReaders[i]->GetEditRate() != mEditRate) {
log_warn("Currently only support available rollout in external reader if "
"external reader edit rate equals group edit rate");
} else if (ext_max_available_rollout > max_available_rollout) {
max_available_rollout = ext_max_available_rollout;
}
}
}

return max_available_rollout;
}

int64_t MXFFileReader::GetFixedLeadFillerOffset() const
{
int64_t fixed_offset = 0;
Expand Down Expand Up @@ -2146,6 +2210,24 @@ int16_t MXFFileReader::GetInternalPrecharge(int64_t position, bool limit_to_avai
return precharge < 0 ? precharge : 0;
}

int64_t MXFFileReader::GetInternalAvailablePrecharge(int64_t position) const
{
CHECK_SUPPORT_PC_RO_INFO;

if (!mEssenceReader)
return 0;

int64_t target_position = position;
if (target_position == CURRENT_POSITION_VALUE)
target_position = GetPosition();

int64_t available_precharge = FROM_ESS_READER_POS(mEssenceReader->LegitimisePosition(0)) - target_position;
if (available_precharge > 0)
available_precharge = 0;

return available_precharge;
}

int16_t MXFFileReader::GetInternalRollout(int64_t position, bool limit_to_available) const
{
CHECK_SUPPORT_PC_RO_INFO;
Expand Down Expand Up @@ -2176,6 +2258,24 @@ int16_t MXFFileReader::GetInternalRollout(int64_t position, bool limit_to_availa
return rollout > 0 ? rollout : 0;
}

int64_t MXFFileReader::GetInternalAvailableRollout(int64_t position) const
{
CHECK_SUPPORT_PC_RO_INFO;

if (!mEssenceReader)
return 0;

int64_t target_position = position;
if (target_position == CURRENT_POSITION_VALUE)
target_position = GetPosition();

int64_t available_rollout = FROM_ESS_READER_POS(mEssenceReader->LegitimisePosition(INT64_MAX)) - target_position;
if (available_rollout < 0)
available_rollout = 0;

return available_rollout;
}

void MXFFileReader::GetInternalAvailableReadLimits(int64_t *start_position, int64_t *duration) const
{
CHECK_SUPPORT_PC_RO_INFO;
Expand Down
10 changes: 10 additions & 0 deletions src/mxf_reader/MXFFileTrackReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,21 @@ int16_t MXFFileTrackReader::GetPrecharge(int64_t position, bool limit_to_availab
return mFileReader->GetInternalPrecharge(position, limit_to_available);
}

int64_t MXFFileTrackReader::GetAvailablePrecharge(int64_t position) const
{
return mFileReader->GetInternalAvailablePrecharge(position);
}

int16_t MXFFileTrackReader::GetRollout(int64_t position, bool limit_to_available) const
{
return mFileReader->GetInternalRollout(position, limit_to_available);
}

int64_t MXFFileTrackReader::GetAvailableRollout(int64_t position) const
{
return mFileReader->GetInternalAvailableRollout(position);
}

void MXFFileTrackReader::SetNextFramePosition(Rational edit_rate, int64_t position)
{
mFileReader->SetNextFramePosition(edit_rate, position);
Expand Down
52 changes: 52 additions & 0 deletions src/mxf_reader/MXFGroupReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,32 @@ int16_t MXFGroupReader::GetMaxPrecharge(int64_t position, bool limit_to_availabl
return max_precharge < 0 ? (int16_t)max_precharge : 0;
}

int64_t MXFGroupReader::GetMaxAvailablePrecharge(int64_t position) const
{
int64_t target_position = position;
if (target_position == CURRENT_POSITION_VALUE)
target_position = GetPosition();

int64_t max_available_precharge = 0;
size_t i;
for (i = 0; i < mReaders.size(); i++) {
if (!mReaders[i]->IsEnabled())
continue;

int64_t mem_max_available_precharge = mReaders[i]->GetMaxAvailablePrecharge(CONVERT_GROUP_POS(target_position));
if (mem_max_available_precharge != 0) {
if (mReaders[i]->GetEditRate() != mEditRate) {
log_warn("Currently only support available precharge in group members if "
"member edit rate equals group edit rate");
} else if (mem_max_available_precharge < max_available_precharge) {
max_available_precharge = mem_max_available_precharge;
}
}
}

return max_available_precharge;
}

int16_t MXFGroupReader::GetMaxRollout(int64_t position, bool limit_to_available) const
{
int64_t max_rollout = 0;
Expand Down Expand Up @@ -548,6 +574,32 @@ int16_t MXFGroupReader::GetMaxRollout(int64_t position, bool limit_to_available)
return max_rollout > 0 ? (int16_t)max_rollout : 0;
}

int64_t MXFGroupReader::GetMaxAvailableRollout(int64_t position) const
{
int64_t target_position = position;
if (target_position == CURRENT_POSITION_VALUE)
target_position = GetPosition();

int64_t max_available_rollout = 0;
size_t i;
for (i = 0; i < mReaders.size(); i++) {
if (!mReaders[i]->IsEnabled())
continue;

int64_t mem_max_available_rollout = mReaders[i]->GetMaxAvailableRollout(CONVERT_GROUP_POS(target_position + 1) - 1);
if (mem_max_available_rollout != 0) {
if (mReaders[i]->GetEditRate() != mEditRate) {
log_warn("Currently only support available rollout in group members if "
"member edit rate equals group edit rate");
} else if (mem_max_available_rollout > max_available_rollout) {
max_available_rollout = mem_max_available_rollout;
}
}
}

return max_available_rollout;
}

int64_t MXFGroupReader::GetFixedLeadFillerOffset() const
{
int64_t fixed_offset = -1;
Expand Down
Loading

0 comments on commit 137fc13

Please sign in to comment.