Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve RDD 9 partition duration #12

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions apps/bmxtranswrap/bmxtranswrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,9 @@ static void usage(const char *cmd)
printf("\n");
printf(" as02/as11op1a/op1a/rdd9/as10:\n");
printf(" --part <interval> Video essence partition interval in frames in input edit rate units, or (floating point) seconds with 's' suffix. Default single partition\n");
printf(" rdd9:\n");
printf(" --fixed-part <interval> Force each partition to have the exact same partition interval in frames, except the last partition\n");
printf(" New partitions are started if the frame count has been reached, even if the next partition does not begin with the start of a GOP\n");
printf("\n");
printf(" as11op1a/as11d10/as11rdd9:\n");
printf(" --dm <fwork> <name> <value> Set descriptive framework property. <fwork> is 'as11' or 'dpp'\n");
Expand Down Expand Up @@ -801,6 +804,7 @@ int main(int argc, const char** argv)
const char *partition_interval_str = 0;
int64_t partition_interval = 0;
bool partition_interval_set = false;
bool fixed_partition_interval = false;
const char *shim_name = 0;
const char *shim_id = 0;
const char *shim_annot = 0;
Expand Down Expand Up @@ -2004,6 +2008,10 @@ int main(int argc, const char** argv)
partition_interval_str = argv[cmdln_index + 1];
cmdln_index++;
}
else if (strcmp(argv[cmdln_index], "--fixed-part") == 0)
{
fixed_partition_interval = true;
}
else if (strcmp(argv[cmdln_index], "--dm") == 0)
{
if (cmdln_index + 3 >= argc)
Expand Down Expand Up @@ -3801,6 +3809,7 @@ int main(int argc, const char** argv)

if (partition_interval_set)
rdd9_clip->SetPartitionInterval(partition_interval);
rdd9_clip->SetFixedPartitionInterval(fixed_partition_interval);
rdd9_clip->SetOutputStartOffset(- precharge);
rdd9_clip->SetOutputEndOffset(- rollout);

Expand Down
9 changes: 9 additions & 0 deletions apps/raw2bmx/raw2bmx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,9 @@ static void usage(const char *cmd)
printf("\n");
printf(" as02/as11op1a/op1a/rdd9/as10:\n");
printf(" --part <interval> Video essence partition interval in frames, or (floating point) seconds with 's' suffix. Default single partition\n");
printf(" rdd9:\n");
printf(" --fixed-part <interval> Force each partition to have the exact same partition interval in frames, except the last partition\n");
printf(" New partitions are started if the frame count has been reached, even if the next partition does not begin with the start of a GOP\n");
printf("\n");
printf(" as11op1a/as11d10:\n");
printf(" --dm <fwork> <name> <value> Set descriptive framework property. <fwork> is 'as11' or 'dpp'\n");
Expand Down Expand Up @@ -891,6 +894,7 @@ int main(int argc, const char** argv)
const char *partition_interval_str = 0;
int64_t partition_interval = 0;
bool partition_interval_set = false;
bool fixed_partition_interval = false;
const char *shim_name = 0;
const char *shim_id = 0;
const char *shim_annot = 0;
Expand Down Expand Up @@ -1310,6 +1314,10 @@ int main(int argc, const char** argv)
partition_interval_str = argv[cmdln_index + 1];
cmdln_index++;
}
else if (strcmp(argv[cmdln_index], "--fixed-part") == 0)
{
fixed_partition_interval = true;
}
else if (strcmp(argv[cmdln_index], "--dm") == 0)
{
if (cmdln_index + 3 >= argc)
Expand Down Expand Up @@ -5079,6 +5087,7 @@ int main(int argc, const char** argv)

if (partition_interval_set)
rdd9_clip->SetPartitionInterval(partition_interval);
rdd9_clip->SetFixedPartitionInterval(fixed_partition_interval);
rdd9_clip->SetOutputStartOffset(output_start_offset);
rdd9_clip->SetOutputEndOffset(- output_end_offset);

Expand Down
2 changes: 2 additions & 0 deletions include/bmx/rdd9_mxf/RDD9File.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class RDD9File
void SetFileSourcePackageUID(mxfUMID package_uid); // default generated
void ReserveHeaderMetadataSpace(uint32_t min_bytes); // default 8192
void SetPartitionInterval(int64_t frame_count); // default 10sec
void SetFixedPartitionInterval(bool enable); // default false
void SetValidator(RDD9Validator *validator);

public:
Expand Down Expand Up @@ -152,6 +153,7 @@ class RDD9File
bool mFirstWrite;

int64_t mPartitionInterval;
bool mFixedPartitionInterval;
int64_t mPartitionFrameCount;

std::vector<RDD9Track*> mTracks;
Expand Down
1 change: 1 addition & 0 deletions include/bmx/rdd9_mxf/RDD9IndexTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ class RDD9IndexTable
std::vector<RDD9IndexTableSegment*> mIndexSegments;
int64_t mDuration;
int64_t mStreamOffset;
int64_t mFirstIndexSegmentCount;

std::vector<RDD9IndexTableSegment*> mWrittenIndexSegments;
};
Expand Down
38 changes: 36 additions & 2 deletions src/rdd9_mxf/RDD9File.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include <bmx/mxf_helper/MXFMCALabelHelper.h>
#include <bmx/Version.h>
#include <bmx/MXFUtils.h>
#include <bmx/Utils.h>
#include <bmx/BMXException.h>
#include <bmx/Logging.h>

Expand All @@ -59,6 +60,22 @@ static const uint32_t MEMORY_WRITE_CHUNK_SIZE = 8192;



typedef struct
{
Rational frame_rate;
int64_t partition_interval;
} RDD9PartitionInterval;

static const RDD9PartitionInterval RDD9_PARTITION_INTERVAL[] =
{
{{24000, 1001}, 240},
{{25, 1}, 240},
{{30000, 1001}, 300},
{{50, 1}, 480},
{{60000, 1001}, 600}
};


static bool compare_track(RDD9Track *left, RDD9Track *right)
{
return left->GetDataDef() < right->GetDataDef();
Expand Down Expand Up @@ -109,11 +126,22 @@ RDD9File::RDD9File(int flavour, File *mxf_file, Rational frame_rate)
mMaterialPackage = 0;
mFileSourcePackage = 0;
mFirstWrite = true;
mPartitionInterval = 10 * frame_rate.numerator / frame_rate.denominator;
mPartitionInterval = 0;
mFixedPartitionInterval = false;
mValidator = 0;
mPartitionFrameCount = 0;
mMXFChecksumFile = 0;

// Target 10 seconds partition duration and use the "should" values from
// RDD 9 2013, Table B.2 if a compliant frame rate is set.
mPartitionInterval = 10 * frame_rate.numerator / frame_rate.denominator;
for (size_t i = 0; i < BMX_ARRAY_SIZE(RDD9_PARTITION_INTERVAL); i++) {
if (frame_rate == RDD9_PARTITION_INTERVAL[i].frame_rate) {
mPartitionInterval = RDD9_PARTITION_INTERVAL[i].partition_interval;
break;
}
}

mTrackIdHelper.SetId("TimecodeTrack", 1);
mTrackIdHelper.SetStartId(MXF_PICTURE_DDEF, 2);
mTrackIdHelper.SetStartId(MXF_SOUND_DDEF, 4);
Expand Down Expand Up @@ -228,6 +256,11 @@ void RDD9File::SetPartitionInterval(int64_t frame_count)
mPartitionInterval = frame_count;
}

void RDD9File::SetFixedPartitionInterval(bool enable)
{
mFixedPartitionInterval = enable;
}

void RDD9File::SetValidator(RDD9Validator *validator)
{
delete mValidator;
Expand Down Expand Up @@ -766,7 +799,8 @@ void RDD9File::WriteContentPackages(bool final_write)
// start body partition at first write or when # frames per partition close to exceeding maximum
if (mFirstWrite ||
(mPartitionInterval > 0 && mPartitionFrameCount > 0 &&
mPartitionFrameCount + MAX_GOP_SIZE >= mPartitionInterval && mIndexTable->CanStartPartition()))
mPartitionFrameCount >= mPartitionInterval &&
(mFixedPartitionInterval || mIndexTable->CanStartPartition())))
{
mMXFFile->openMemoryFile(MEMORY_WRITE_CHUNK_SIZE);

Expand Down
18 changes: 17 additions & 1 deletion src/rdd9_mxf/RDD9IndexTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ RDD9IndexTable::RDD9IndexTable(uint32_t index_sid, uint32_t body_sid, Rational e
mIndexEntrySize = 0;
mDuration = 0;
mStreamOffset = 0;
mFirstIndexSegmentCount = 0;
}

RDD9IndexTable::~RDD9IndexTable()
Expand Down Expand Up @@ -479,6 +480,8 @@ void RDD9IndexTable::WriteVBESegments(File *mxf_file, Partition *partition, vect
{
size_t i;
for (i = 0; i < segments.size(); i++) {
int64_t segment_start_file_pos = mxf_file->tell();

IndexTableSegment *segment = segments[i]->GetSegment();
ByteArray *entries = segments[i]->GetEntries();

Expand All @@ -498,7 +501,20 @@ void RDD9IndexTable::WriteVBESegments(File *mxf_file, Partition *partition, vect
segment->writeIndexEntryArrayHeader(mxf_file, mSliceCount, 0, (uint32_t)segment->getIndexDuration());
mxf_file->write(entries->GetBytes(), entries->GetSize());

partition->fillToKag(mxf_file);
// The index byte count for all index segments should all be equal.
// The index durations for all index segments, except the last, should all be equal.
// The last index segment may have a shorter index duration and the code below should
// ensure that it has the same index byte count (as the first index segment).
if (mFirstIndexSegmentCount == 0) {
mFirstIndexSegmentCount = mxf_file->tell() - segment_start_file_pos;
partition->fillToKag(mxf_file);
} else {
int64_t current_count = mxf_file->tell() - segment_start_file_pos;
if (current_count < mFirstIndexSegmentCount)
partition->allocateSpaceToKag(mxf_file, mFirstIndexSegmentCount - current_count);
else
partition->fillToKag(mxf_file);
}
}
}

2 changes: 1 addition & 1 deletion test/as10/test_as10.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ set(create_command ${RAW2BMX}
-f 25
-y 22:22:22:22
--single-pass
--part 25
--part 12
-o ${output_file_1}
--dm-file as10 ${TEST_SOURCE_DIR}/as10_core_framework.txt
--shim-name high_hd_2014
Expand Down
1 change: 1 addition & 0 deletions test/rdd9_mxf/mpeg2lg_422p_hl_1080i_fixed_part.md5
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
864b5a1e6b9e1cc4e539dd48a5862d70
37 changes: 26 additions & 11 deletions test/rdd9_mxf/test_common.cmake
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
include("${TEST_SOURCE_DIR}/../testing.cmake")


function(run_test test frame_rate duration)
function(run_test test frame_rate part fixed_part duration)
if(frame_rate STREQUAL "x")
set(frame_rate)
set(rate_opt)
else()
set(rate_opt -f ${frame_rate})
endif()

if(fixed_part STREQUAL "true")
set(fixed_part_opt --fixed-part)
set(output_suffix _fixed_part)
else()
set(fixed_part_opt)
set(output_suffix)
endif()

if(TEST_MODE STREQUAL "check")
set(output_file test_${test}${frame_rate}.mxf)
set(output_file test_${test}${frame_rate}${output_suffix}.mxf)
elseif(TEST_MODE STREQUAL "samples")
file(MAKE_DIRECTORY ${BMX_TEST_SAMPLES_DIR})

set(output_file ${BMX_TEST_SAMPLES_DIR}/test_${test}${frame_rate}.mxf)
set(output_file ${BMX_TEST_SAMPLES_DIR}/test_${test}${frame_rate}${output_suffix}.mxf)
else()
set(output_file test_${test}${frame_rate}.mxf)
set(output_file test_${test}${frame_rate}${output_suffix}.mxf)
endif()

set(checksum_file ${test}${frame_rate}.md5)
set(checksum_file ${test}${frame_rate}${output_suffix}.md5)

set(create_test_audio ${CREATE_TEST_ESSENCE}
-t 1
Expand All @@ -33,7 +41,8 @@ function(run_test test frame_rate duration)
-y 10:11:12:13
${rate_opt}
--clip test
--part 12
--part ${part}
${fixed_part_opt}
-o ${output_file}
-a 16:9 --${test} video_${test}
-q 16 --locked true --pcm audio_${test}
Expand All @@ -59,24 +68,30 @@ endfunction()

function(run_tests tests duration)
list(LENGTH tests len_tests)
math(EXPR max_index "(${len_tests} / 3) - 1")
math(EXPR max_index "(${len_tests} / 5) - 1")

foreach(index RANGE ${max_index})
math(EXPR test_index "${index} * 3")
math(EXPR test_index "${index} * 5")
list(GET tests ${test_index} test)

math(EXPR test_ess_type_index "${index} * 3 + 1")
math(EXPR test_ess_type_index "${index} * 5 + 1")
list(GET tests ${test_ess_type_index} test_ess_type)

math(EXPR test_frame_rate_index "${index} * 3 + 2")
math(EXPR test_frame_rate_index "${index} * 5 + 2")
list(GET tests ${test_frame_rate_index} test_frame_rate)

math(EXPR test_part_index "${index} * 5 + 3")
list(GET tests ${test_part_index} test_part)

math(EXPR test_fixed_part_index "${index} * 5 + 4")
list(GET tests ${test_fixed_part_index} test_fixed_part)

set(create_test_video ${CREATE_TEST_ESSENCE}
-t ${test_ess_type}
-d ${duration}
video_${test}
)

run_test(${test} ${test_frame_rate} ${duration})
run_test(${test} ${test_frame_rate} ${test_part} ${test_fixed_part} ${duration})
endforeach()
endfunction()
7 changes: 4 additions & 3 deletions test/rdd9_mxf/test_mpeg2lg.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
include("${TEST_SOURCE_DIR}/test_common.cmake")

set(tests
mpeg2lg_422p_hl_1080i 14 "x"
mpeg2lg_mp_h14_1080i 15 "x"
mpeg2lg_mp_hl_1920_1080i 16 "x"
mpeg2lg_422p_hl_1080i 14 "x" "12" "false"
mpeg2lg_mp_h14_1080i 15 "x" "12" "false"
mpeg2lg_mp_hl_1920_1080i 16 "x" "12" "false"
mpeg2lg_422p_hl_1080i 14 "x" "6" "true"
)

run_tests("${tests}" 24)