From 881505b8fbb13b4dbb7a35fe108f537e56ebd6de Mon Sep 17 00:00:00 2001 From: Philip de Nier Date: Mon, 11 Nov 2024 10:04:11 +0000 Subject: [PATCH] Fix variable size ANV/VBI alongside variables size video The default index table entry flag is 0x80, not 0x00. --- src/mxf_op1a/OP1AIndexTable.cpp | 6 +- src/rdd9_mxf/RDD9IndexTable.cpp | 6 +- test/create_test_essence.cpp | 97 ++++++++++++++++++++++++++++++--- test/mxf_op1a/anc.md5 | 2 +- test/mxf_op1a/anc_klv.md5 | 1 + test/mxf_op1a/test_ancvbi.cmake | 42 +++++++++----- test/mxf_op1a/vbi.md5 | 2 +- test/mxf_op1a/vbi_klv.md5 | 1 + test/rdd9_mxf/anc_klv.md5 | 1 + test/rdd9_mxf/test_ancvbi.cmake | 32 ++++++++--- test/rdd9_mxf/vbi_klv.md5 | 1 + 11 files changed, 151 insertions(+), 40 deletions(-) create mode 100644 test/mxf_op1a/anc_klv.md5 create mode 100644 test/mxf_op1a/vbi_klv.md5 create mode 100644 test/rdd9_mxf/anc_klv.md5 create mode 100644 test/rdd9_mxf/vbi_klv.md5 diff --git a/src/mxf_op1a/OP1AIndexTable.cpp b/src/mxf_op1a/OP1AIndexTable.cpp index 84fd3e3b..4d81e26d 100644 --- a/src/mxf_op1a/OP1AIndexTable.cpp +++ b/src/mxf_op1a/OP1AIndexTable.cpp @@ -69,7 +69,7 @@ OP1AIndexEntry::OP1AIndexEntry() { temporal_offset = 0; key_frame_offset = 0; - flags = 0; + flags = 0x80; can_start_partition = true; } @@ -84,13 +84,13 @@ OP1AIndexEntry::OP1AIndexEntry(int8_t temporal_offset_, int8_t key_frame_offset_ bool OP1AIndexEntry::IsDefault() { - return temporal_offset == 0 && key_frame_offset == 0 && flags == 0; + return temporal_offset == 0 && key_frame_offset == 0 && flags == 0x80; } bool OP1AIndexEntry::IsCompatible(const OP1AIndexEntry &entry) { // compatible if current entry is the default entry or the new entry equals the current entry - return (temporal_offset == 0 && key_frame_offset == 0 && flags == 0) || + return IsDefault() || (temporal_offset == entry.temporal_offset && key_frame_offset == entry.key_frame_offset && flags == entry.flags); } diff --git a/src/rdd9_mxf/RDD9IndexTable.cpp b/src/rdd9_mxf/RDD9IndexTable.cpp index 9c61c8aa..bc342c4b 100644 --- a/src/rdd9_mxf/RDD9IndexTable.cpp +++ b/src/rdd9_mxf/RDD9IndexTable.cpp @@ -69,7 +69,7 @@ RDD9IndexEntry::RDD9IndexEntry() { temporal_offset = 0; key_frame_offset = 0; - flags = 0; + flags = 0x80; can_start_partition = true; } @@ -84,13 +84,13 @@ RDD9IndexEntry::RDD9IndexEntry(int8_t temporal_offset_, int8_t key_frame_offset_ bool RDD9IndexEntry::IsDefault() { - return temporal_offset == 0 && key_frame_offset == 0 && flags == 0; + return temporal_offset == 0 && key_frame_offset == 0 && flags == 0x80; } bool RDD9IndexEntry::IsCompatible(const RDD9IndexEntry &entry) { // compatible if current entry is the default entry or the new entry equals the current entry - return (temporal_offset == 0 && key_frame_offset == 0 && flags == 0) || + return IsDefault() || (temporal_offset == entry.temporal_offset && key_frame_offset == entry.key_frame_offset && flags == entry.flags); } diff --git a/test/create_test_essence.cpp b/test/create_test_essence.cpp index 9c6ff6d6..269088f1 100644 --- a/test/create_test_essence.cpp +++ b/test/create_test_essence.cpp @@ -117,7 +117,9 @@ typedef enum TYPE_RDD36_422_ITU2020 = 58, TYPE_MPEG2LG_MP_ML_576I = 59, TYPE_MPEG2LG_MP_ML_576I_4_3 = 60, - TYPE_END = 61, + TYPE_KLV_ANC_DATA_VAR_SIZE = 61, + TYPE_KLV_VBI_DATA_VAR_SIZE = 62, + TYPE_END = 63, } EssenceType; typedef struct @@ -902,30 +904,96 @@ static void write_avid_alpha(FILE *file, int type, unsigned int duration) write_data(file, duration * frame_size); } -static void write_anc_data(FILE *file, unsigned int duration) +static void write_anc_data(FILE *file, unsigned int duration, bool klv_var_size) { - static const unsigned char anc_frame[24] = + static const unsigned char core_anc_frame[24] = {0x00, 0x01, // single line / packet 0x00, 0x09, 0x01, 0x04, 0x00, 0x07, // line 9, VANCFrame, ANC_8_BIT_COMP_LUMA, 7 samples 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, // payload array header: 8 x 1 bytes 0x45, 0x04, 0x04, 0x21, 0x22, 0x23, 0x24, 0x00}; // payload array: DID (1), SDID (1), DC (1), UDW (4), padding (1) + // Any key will do as it is discarded when parsing the data + static const unsigned char klv_key[16] = {0x41, 0x4e, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + // Odd and even frame data and sizes + unsigned char *anc_data[2]; + size_t anc_data_size[2]; + + if (klv_var_size) { + anc_data_size[0] = 16 + 1 + sizeof(core_anc_frame); + anc_data[0] = new unsigned char[anc_data_size[0]]; + memcpy(anc_data[0], klv_key, 16); + anc_data[0][16] = anc_data_size[0] - 17; + memcpy(&anc_data[0][17], core_anc_frame, sizeof(core_anc_frame)); + + // Add an extra padding byte to the odd frame + anc_data_size[1] = 16 + 1 + sizeof(core_anc_frame) + 1; + anc_data[1] = new unsigned char[anc_data_size[1]]; + memcpy(anc_data[1], klv_key, 16); + anc_data[1][16] = anc_data_size[1] - 17; + memcpy(&anc_data[1][17], core_anc_frame, sizeof(core_anc_frame)); + anc_data[1][16 + 1 + 11] = 0x09; + anc_data[1][anc_data_size[1] - 1] = 0x00; + } else { + anc_data[0] = const_cast(core_anc_frame); + anc_data[1] = const_cast(core_anc_frame); + anc_data_size[0] = sizeof(core_anc_frame); + anc_data_size[1] = sizeof(core_anc_frame); + } unsigned int i; for (i = 0; i < duration; i++) - write_buffer(file, anc_frame, sizeof(anc_frame)); + write_buffer(file, anc_data[i % 2], anc_data_size[i % 2]); + + if (klv_var_size) { + delete [] anc_data[0]; + delete [] anc_data[1]; + } } -static void write_vbi_data(FILE *file, unsigned int duration) +static void write_vbi_data(FILE *file, unsigned int duration, bool klv_var_size) { - static const unsigned char vbi_frame[24] = + static const unsigned char core_vbi_frame[24] = {0x00, 0x01, // single line 0x00, 0x15, 0x01, 0x04, 0x00, 0x08, // line 21, VBIFrame, VBI_8_BIT_COMP_LUMA, 8 samples 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, // payload array header: 8 x 1 bytes 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47}; // payload array + // Any key will do as it is discarded when parsing the data + static const unsigned char klv_key[16] = {0x56, 0x42, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + // Odd and even frame data and sizes + unsigned char *vbi_data[2]; + size_t vbi_data_size[2]; + + if (klv_var_size) { + vbi_data_size[0] = 16 + 1 + sizeof(core_vbi_frame); + vbi_data[0] = new unsigned char[vbi_data_size[0]]; + memcpy(vbi_data[0], klv_key, 16); + vbi_data[0][16] = vbi_data_size[0] - 17; + memcpy(&vbi_data[0][17], core_vbi_frame, sizeof(core_vbi_frame)); + + // Add an extra padding byte to the odd frame + vbi_data_size[1] = 16 + 1 + sizeof(core_vbi_frame) + 1; + vbi_data[1] = new unsigned char[vbi_data_size[1]]; + memcpy(vbi_data[1], klv_key, 16); + vbi_data[1][16] = vbi_data_size[1] - 17; + memcpy(&vbi_data[1][17], core_vbi_frame, sizeof(core_vbi_frame)); + vbi_data[1][16 + 1 + 11] = 0x09; + vbi_data[1][vbi_data_size[1] - 1] = 0x00; + } else { + vbi_data[0] = const_cast(core_vbi_frame); + vbi_data[1] = const_cast(core_vbi_frame); + vbi_data_size[0] = sizeof(core_vbi_frame); + vbi_data_size[1] = sizeof(core_vbi_frame); + } unsigned int i; for (i = 0; i < duration; i++) - write_buffer(file, vbi_frame, sizeof(vbi_frame)); + write_buffer(file, vbi_data[i % 2], vbi_data_size[i % 2]); + + if (klv_var_size) { + delete [] vbi_data[0]; + delete [] vbi_data[1]; + } } @@ -990,6 +1058,11 @@ static void print_usage(const char *cmd) fprintf(stderr, " 55: RDD-36 422 Profile\n"); fprintf(stderr, " 56: RDD-36 4444 Profile\n"); fprintf(stderr, " 57: 16-bit PCM with duration in samples\n"); + fprintf(stderr, " 58: RDD-36 422 ITU 2020\n"); + fprintf(stderr, " 59: MPEG-2 Long GOP MP@ML 576i\n"); + fprintf(stderr, " 60: MPEG-2 Long GOP MP@ML 576i 4:3\n"); + fprintf(stderr, " 61: variable size ANC data in KLV\n"); + fprintf(stderr, " 62: variable size VBI data in KLV\n"); } int main(int argc, const char **argv) @@ -1190,10 +1263,16 @@ int main(int argc, const char **argv) write_pcm(file, 3, duration); break; case TYPE_ANC_DATA: - write_anc_data(file, duration); + write_anc_data(file, duration, false); + break; + case TYPE_KLV_ANC_DATA_VAR_SIZE: + write_anc_data(file, duration, true); break; case TYPE_VBI_DATA: - write_vbi_data(file, duration); + write_vbi_data(file, duration, false); + break; + case TYPE_KLV_VBI_DATA_VAR_SIZE: + write_vbi_data(file, duration, true); break; case TYPE_16BIT_PCM_SAMPLES: write_pcm_samples(file, 2, duration); diff --git a/test/mxf_op1a/anc.md5 b/test/mxf_op1a/anc.md5 index 2473996d..e704d77c 100644 --- a/test/mxf_op1a/anc.md5 +++ b/test/mxf_op1a/anc.md5 @@ -1 +1 @@ -3e540ddd8608253d9b0ae75dd76e12e2 \ No newline at end of file +730b76ff77171d65cf81cb9f776a2d54 \ No newline at end of file diff --git a/test/mxf_op1a/anc_klv.md5 b/test/mxf_op1a/anc_klv.md5 new file mode 100644 index 00000000..644ef6b9 --- /dev/null +++ b/test/mxf_op1a/anc_klv.md5 @@ -0,0 +1 @@ +68bb6d216edc005ee77a997dfb19159d \ No newline at end of file diff --git a/test/mxf_op1a/test_ancvbi.cmake b/test/mxf_op1a/test_ancvbi.cmake index 5a9f0de5..370206aa 100644 --- a/test/mxf_op1a/test_ancvbi.cmake +++ b/test/mxf_op1a/test_ancvbi.cmake @@ -2,7 +2,7 @@ include("${TEST_SOURCE_DIR}/test_common.cmake") -function(run_ancvbi_test test data_type) +function(run_ancvbi_test test input_type data_type klv_opt) if(TEST_MODE STREQUAL "check") set(output_file test_${test}.mxf) elseif(TEST_MODE STREQUAL "samples") @@ -13,21 +13,27 @@ function(run_ancvbi_test test data_type) set(output_file test_${test}.mxf) endif() + if(${klv_opt} STREQUAL "TRUE") + set(klv_size_opt "--klv;s") + else() + set(klv_size_opt "--${test}-const;24") + endif() + set(create_test_video ${CREATE_TEST_ESSENCE} - -t 7 - -d 3 + -t 14 + -d 12 video_${test} ) set(create_test_audio ${CREATE_TEST_ESSENCE} -t 1 - -d 3 + -d 12 audio_${test} ) set(create_test_data ${CREATE_TEST_ESSENCE} -t ${data_type} - -d 3 + -d 12 data_${test} ) @@ -35,9 +41,9 @@ function(run_ancvbi_test test data_type) --regtest -t op1a -o ${output_file} - --avci100_1080i video_${test} + --mpeg2lg_422p_hl_1080i video_${test} -q 16 --pcm audio_${test} - --${test}-const 24 --${test} data_${test} + ${klv_size_opt} --${input_type} data_${test} ) run_test_a( @@ -58,19 +64,27 @@ function(run_ancvbi_test test data_type) endfunction() set(tests - anc 43 - vbi 44 + anc anc 43 FALSE + vbi vbi 44 FALSE + anc_klv anc 61 TRUE + vbi_klv vbi 62 TRUE ) list(LENGTH tests len_tests) -math(EXPR max_index "(${len_tests} / 2) - 1") +math(EXPR max_index "(${len_tests} / 4) - 1") foreach(index RANGE ${max_index}) - math(EXPR test_index "${index} * 2") + math(EXPR test_index "${index} * 4") list(GET tests ${test_index} test) - - math(EXPR test_ess_type_index "${index} * 2 + 1") + + math(EXPR test_input_type_index "${index} * 4 + 1") + list(GET tests ${test_input_type_index} test_input_type) + + math(EXPR test_ess_type_index "${index} * 4 + 2") list(GET tests ${test_ess_type_index} test_ess_type) - run_ancvbi_test(${test} ${test_ess_type}) + math(EXPR test_klv_opt_index "${index} * 4 + 3") + list(GET tests ${test_klv_opt_index} test_klv_opt) + + run_ancvbi_test(${test} ${test_input_type} ${test_ess_type} ${test_klv_opt}) endforeach() diff --git a/test/mxf_op1a/vbi.md5 b/test/mxf_op1a/vbi.md5 index f3188493..2ef080a0 100644 --- a/test/mxf_op1a/vbi.md5 +++ b/test/mxf_op1a/vbi.md5 @@ -1 +1 @@ -58a8e6c0c8e31e54f796be56e2c0b75a \ No newline at end of file +fb2139f4d8ecdfb457737967ad5cc4cc \ No newline at end of file diff --git a/test/mxf_op1a/vbi_klv.md5 b/test/mxf_op1a/vbi_klv.md5 new file mode 100644 index 00000000..2f3f0378 --- /dev/null +++ b/test/mxf_op1a/vbi_klv.md5 @@ -0,0 +1 @@ +92e1d604207d6628a1763516b96a3b4f \ No newline at end of file diff --git a/test/rdd9_mxf/anc_klv.md5 b/test/rdd9_mxf/anc_klv.md5 new file mode 100644 index 00000000..3e6a9737 --- /dev/null +++ b/test/rdd9_mxf/anc_klv.md5 @@ -0,0 +1 @@ +1a445e0924e22ce15e27e3c90ec70c78 \ No newline at end of file diff --git a/test/rdd9_mxf/test_ancvbi.cmake b/test/rdd9_mxf/test_ancvbi.cmake index 78365632..f70ef9a5 100644 --- a/test/rdd9_mxf/test_ancvbi.cmake +++ b/test/rdd9_mxf/test_ancvbi.cmake @@ -2,7 +2,7 @@ include("${TEST_SOURCE_DIR}/test_common.cmake") -function(run_ancvbi_test test data_type) +function(run_ancvbi_test test input_type data_type klv_opt) if(TEST_MODE STREQUAL "check") set(output_file test.mxf) elseif(TEST_MODE STREQUAL "samples") @@ -13,6 +13,12 @@ function(run_ancvbi_test test data_type) set(output_file test.mxf) endif() + if(${klv_opt} STREQUAL "TRUE") + set(klv_size_opt "--klv;s") + else() + set(klv_size_opt "--${test}-const;24") + endif() + set(create_test_video ${CREATE_TEST_ESSENCE} -t 14 -d 24 @@ -38,7 +44,7 @@ function(run_ancvbi_test test data_type) --mpeg2lg_422p_hl_1080i video -q 16 --pcm audio -q 16 --pcm audio - --${test}-const 24 --${test} data + ${klv_size_opt} --${input_type} data ) run_test_a( @@ -59,19 +65,27 @@ function(run_ancvbi_test test data_type) endfunction() set(tests - anc 43 - vbi 44 + anc anc 43 FALSE + vbi vbi 44 FALSE + anc_klv anc 61 TRUE + vbi_klv vbi 62 TRUE ) list(LENGTH tests len_tests) -math(EXPR max_index "(${len_tests} / 2) - 1") +math(EXPR max_index "(${len_tests} / 4) - 1") foreach(index RANGE ${max_index}) - math(EXPR test_index "${index} * 2") + math(EXPR test_index "${index} * 4") list(GET tests ${test_index} test) - - math(EXPR test_ess_type_index "${index} * 2 + 1") + + math(EXPR test_input_type_index "${index} * 4 + 1") + list(GET tests ${test_input_type_index} test_input_type) + + math(EXPR test_ess_type_index "${index} * 4 + 2") list(GET tests ${test_ess_type_index} test_ess_type) - run_ancvbi_test(${test} ${test_ess_type}) + math(EXPR test_klv_opt_index "${index} * 4 + 3") + list(GET tests ${test_klv_opt_index} test_klv_opt) + + run_ancvbi_test(${test} ${test_input_type} ${test_ess_type} ${test_klv_opt}) endforeach() diff --git a/test/rdd9_mxf/vbi_klv.md5 b/test/rdd9_mxf/vbi_klv.md5 new file mode 100644 index 00000000..66564361 --- /dev/null +++ b/test/rdd9_mxf/vbi_klv.md5 @@ -0,0 +1 @@ +210dc3cd662c9a697fdaa2313870a792 \ No newline at end of file