From 510d0b85e3a8a0fb6e359adb4552d55f21070d95 Mon Sep 17 00:00:00 2001 From: Philip de Nier Date: Fri, 5 May 2023 15:02:35 +0100 Subject: [PATCH] rdd9: add --fixed-part option to force part interval A new partition is started at the set partition frame count even if the new partition doesn't begin with a GOP start. --- apps/bmxtranswrap/bmxtranswrap.cpp | 9 +++++ apps/raw2bmx/raw2bmx.cpp | 9 +++++ include/bmx/rdd9_mxf/RDD9File.h | 2 + src/rdd9_mxf/RDD9File.cpp | 9 ++++- .../mpeg2lg_422p_hl_1080i_fixed_part.md5 | 1 + test/rdd9_mxf/test_common.cmake | 37 +++++++++++++------ test/rdd9_mxf/test_mpeg2lg.cmake | 7 ++-- 7 files changed, 59 insertions(+), 15 deletions(-) create mode 100644 test/rdd9_mxf/mpeg2lg_422p_hl_1080i_fixed_part.md5 diff --git a/apps/bmxtranswrap/bmxtranswrap.cpp b/apps/bmxtranswrap/bmxtranswrap.cpp index bc9d07dd..987e0a62 100644 --- a/apps/bmxtranswrap/bmxtranswrap.cpp +++ b/apps/bmxtranswrap/bmxtranswrap.cpp @@ -541,6 +541,9 @@ static void usage(const char *cmd) printf("\n"); printf(" as02/as11op1a/op1a/rdd9/as10:\n"); printf(" --part 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 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 Set descriptive framework property. is 'as11' or 'dpp'\n"); @@ -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; @@ -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) @@ -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); diff --git a/apps/raw2bmx/raw2bmx.cpp b/apps/raw2bmx/raw2bmx.cpp index 27a94c73..74eecf3e 100644 --- a/apps/raw2bmx/raw2bmx.cpp +++ b/apps/raw2bmx/raw2bmx.cpp @@ -486,6 +486,9 @@ static void usage(const char *cmd) printf("\n"); printf(" as02/as11op1a/op1a/rdd9/as10:\n"); printf(" --part Video essence partition interval in frames, or (floating point) seconds with 's' suffix. Default single partition\n"); + printf(" rdd9:\n"); + printf(" --fixed-part 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 Set descriptive framework property. is 'as11' or 'dpp'\n"); @@ -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; @@ -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) @@ -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); diff --git a/include/bmx/rdd9_mxf/RDD9File.h b/include/bmx/rdd9_mxf/RDD9File.h index c988c52b..18e96aaa 100644 --- a/include/bmx/rdd9_mxf/RDD9File.h +++ b/include/bmx/rdd9_mxf/RDD9File.h @@ -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: @@ -152,6 +153,7 @@ class RDD9File bool mFirstWrite; int64_t mPartitionInterval; + bool mFixedPartitionInterval; int64_t mPartitionFrameCount; std::vector mTracks; diff --git a/src/rdd9_mxf/RDD9File.cpp b/src/rdd9_mxf/RDD9File.cpp index 10bbd41b..5a856302 100644 --- a/src/rdd9_mxf/RDD9File.cpp +++ b/src/rdd9_mxf/RDD9File.cpp @@ -127,6 +127,7 @@ RDD9File::RDD9File(int flavour, File *mxf_file, Rational frame_rate) mFileSourcePackage = 0; mFirstWrite = true; mPartitionInterval = 0; + mFixedPartitionInterval = false; mValidator = 0; mPartitionFrameCount = 0; mMXFChecksumFile = 0; @@ -255,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; @@ -793,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 >= mPartitionInterval && mIndexTable->CanStartPartition())) + mPartitionFrameCount >= mPartitionInterval && + (mFixedPartitionInterval || mIndexTable->CanStartPartition()))) { mMXFFile->openMemoryFile(MEMORY_WRITE_CHUNK_SIZE); diff --git a/test/rdd9_mxf/mpeg2lg_422p_hl_1080i_fixed_part.md5 b/test/rdd9_mxf/mpeg2lg_422p_hl_1080i_fixed_part.md5 new file mode 100644 index 00000000..ead57ea2 --- /dev/null +++ b/test/rdd9_mxf/mpeg2lg_422p_hl_1080i_fixed_part.md5 @@ -0,0 +1 @@ +864b5a1e6b9e1cc4e539dd48a5862d70 \ No newline at end of file diff --git a/test/rdd9_mxf/test_common.cmake b/test/rdd9_mxf/test_common.cmake index 80c32754..c96b0366 100644 --- a/test/rdd9_mxf/test_common.cmake +++ b/test/rdd9_mxf/test_common.cmake @@ -1,7 +1,7 @@ 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) @@ -9,17 +9,25 @@ function(run_test test frame_rate duration) 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 @@ -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} @@ -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() diff --git a/test/rdd9_mxf/test_mpeg2lg.cmake b/test/rdd9_mxf/test_mpeg2lg.cmake index e04ce29a..997ea96c 100644 --- a/test/rdd9_mxf/test_mpeg2lg.cmake +++ b/test/rdd9_mxf/test_mpeg2lg.cmake @@ -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)