Skip to content
This repository was archived by the owner on Sep 29, 2025. It is now read-only.

Commit 4ec9406

Browse files
author
Philip de Nier
committed
bmxtranswrap: add --strip-anc option
Allows not passing through specific ANC data types without having to specifiy each ANC type to pass through using the --pass-anc option. This allows stripping certain ANC types whilst passing through any other ANC type.
1 parent 846b0cc commit 4ec9406

18 files changed

+306
-11
lines changed

apps/bmxtranswrap/bmxtranswrap.cpp

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,32 @@ static bool regtest_output_track_map_comp(const TrackMapper::OutputTrackMap &lef
137137
return left.data_def < right.data_def;
138138
}
139139

140-
static bool filter_anc_manifest_element(const ANCManifestElement *element, set<ANCDataType> &filter)
140+
static bool filter_passing_anc_data_type(ANCDataType data_type, set<ANCDataType> &filter)
141+
{
142+
set<ANCDataType>::const_iterator iter;
143+
for (iter = filter.begin(); iter != filter.end(); iter++) {
144+
if (*iter == ALL_ANC_DATA || *iter == data_type)
145+
return true;
146+
}
147+
148+
return false;
149+
}
150+
151+
static bool passing_anc_data_type(ANCDataType data_type, set<ANCDataType> &pass_filter, set<ANCDataType> &strip_filter)
152+
{
153+
bool passing = false;
154+
if (!pass_filter.empty())
155+
passing = filter_passing_anc_data_type(data_type, pass_filter);
156+
else if (!strip_filter.empty())
157+
passing = true; // Default of pass filter changes to ALL_ANC_DATA if strip filter not empty
158+
159+
if (passing && !strip_filter.empty())
160+
passing = !filter_passing_anc_data_type(data_type, strip_filter);
161+
162+
return passing;
163+
}
164+
165+
static bool single_filter_anc_manifest_element(const ANCManifestElement *element, set<ANCDataType> &filter)
141166
{
142167
set<ANCDataType>::const_iterator iter;
143168
for (iter = filter.begin(); iter != filter.end(); iter++) {
@@ -167,11 +192,25 @@ static bool filter_anc_manifest_element(const ANCManifestElement *element, set<A
167192
return false;
168193
}
169194

170-
static bool filter_anc_manifest(const MXFDataTrackInfo *data_info, set<ANCDataType> &filter)
195+
static bool filter_anc_manifest_element(const ANCManifestElement *element, set<ANCDataType> &pass_filter, set<ANCDataType> &strip_filter)
196+
{
197+
bool pass = false;
198+
if (!pass_filter.empty())
199+
pass = single_filter_anc_manifest_element(element, pass_filter);
200+
else if (!strip_filter.empty())
201+
pass = true; // Default of pass filter changes to ALL_ANC_DATA if strip filter not empty
202+
203+
if (pass && !strip_filter.empty())
204+
pass = !single_filter_anc_manifest_element(element, strip_filter);
205+
206+
return pass;
207+
}
208+
209+
static bool filter_anc_manifest(const MXFDataTrackInfo *data_info, set<ANCDataType> &pass_filter, set<ANCDataType> &strip_filter)
171210
{
172211
size_t i;
173212
for (i = 0; i < data_info->anc_manifest.size(); i++) {
174-
if (filter_anc_manifest_element(&data_info->anc_manifest[i], filter))
213+
if (filter_anc_manifest_element(&data_info->anc_manifest[i], pass_filter, strip_filter))
175214
return true;
176215
}
177216

@@ -300,11 +339,11 @@ static uint32_t read_samples(MXFReader *reader, const vector<uint32_t> &sample_s
300339
return num_read;
301340
}
302341

303-
static void write_anc_samples(OutputTrack *output_track, Frame *frame, set<ANCDataType> &filter, bmx::ByteArray &anc_buffer)
342+
static void write_anc_samples(OutputTrack *output_track, Frame *frame, set<ANCDataType> &pass_filter, set<ANCDataType> &strip_filter, bmx::ByteArray &anc_buffer)
304343
{
305344
BMX_CHECK(frame->num_samples == 1);
306345

307-
if (filter.empty() || (filter.size() == 1 && (*filter.begin()) == ALL_ANC_DATA)) {
346+
if (passing_anc_data_type(ALL_ANC_DATA, pass_filter, strip_filter)) {
308347
output_track->WriteSamples(0, (unsigned char*)frame->GetBytes(), frame->GetSize(), frame->num_samples);
309348
return;
310349
}
@@ -317,7 +356,7 @@ static void write_anc_samples(OutputTrack *output_track, Frame *frame, set<ANCDa
317356
for (i = 0; i < input_element.lines.size(); i++) {
318357
ANCManifestElement manifest_element;
319358
manifest_element.Parse(&input_element.lines[i]);
320-
if (filter_anc_manifest_element(&manifest_element, filter))
359+
if (filter_anc_manifest_element(&manifest_element, pass_filter, strip_filter))
321360
output_element.lines.push_back(input_element.lines[i]);
322361
}
323362

@@ -582,6 +621,9 @@ static void usage(const char *cmd)
582621
printf(" sdp : SMPTE RDD 8 / OP-47 Subtitling Distribution Packet data\n");
583622
printf(" st12 : SMPTE ST 12 Ancillary timecode\n");
584623
printf(" st334 : SMPTE ST 334-1 EIA 708B, EIA 608 and data broadcast (DTV)\n");
624+
printf(" --strip-anc <filter> Don't pass through ST 436 ANC data tracks\n");
625+
printf(" <filter> is a comma separated list of ANC data types to not pass through. The types are listed in the --pass-anc option\n");
626+
printf(" This filter is applied after --pass-anc. The --pass-anc option will default to 'all' when --strip-anc is used\n");
585627
printf(" --pass-vbi Pass through ST 436 VBI data tracks\n");
586628
printf(" --st436-mf <count> Set the <count> of frames to examine for ST 436 ANC/VBI manifest info. Default is %u\n", DEFAULT_ST436_MANIFEST_COUNT);
587629
printf(" The manifest is used at the start to determine whether an output ANC data track is created\n");
@@ -927,6 +969,7 @@ int main(int argc, const char** argv)
927969
bool avid_gf = false;
928970
int64_t avid_gf_duration = -1;
929971
set<ANCDataType> pass_anc;
972+
set<ANCDataType> strip_anc;
930973
bool pass_vbi = false;
931974
uint32_t st436_manifest_count = DEFAULT_ST436_MANIFEST_COUNT;
932975
uint32_t anc_const_size = 0;
@@ -2154,6 +2197,22 @@ int main(int argc, const char** argv)
21542197
}
21552198
cmdln_index++;
21562199
}
2200+
else if (strcmp(argv[cmdln_index], "--strip-anc") == 0)
2201+
{
2202+
if (cmdln_index + 1 >= argc)
2203+
{
2204+
usage_ref(argv[0]);
2205+
fprintf(stderr, "Missing argument for Option '%s'\n", argv[cmdln_index]);
2206+
return 1;
2207+
}
2208+
if (!parse_anc_data_types(argv[cmdln_index + 1], &strip_anc))
2209+
{
2210+
usage_ref(argv[0]);
2211+
fprintf(stderr, "Invalid value '%s' for Option '%s'\n", argv[cmdln_index + 1], argv[cmdln_index]);
2212+
return 1;
2213+
}
2214+
cmdln_index++;
2215+
}
21572216
else if (strcmp(argv[cmdln_index], "--pass-vbi") == 0)
21582217
{
21592218
pass_vbi = true;
@@ -2784,9 +2843,9 @@ int main(int argc, const char** argv)
27842843
}
27852844
}
27862845

2787-
if (st2020_max_size && (pass_anc.size() != 1 || *pass_anc.begin() != ST2020_ANC_DATA)) {
2846+
if (st2020_max_size && !passing_anc_data_type(ST2020_ANC_DATA, pass_anc, strip_anc)) {
27882847
usage_ref(argv[0]);
2789-
fprintf(stderr, "Option '--st2020-max' requires '--pass st2020'\n");
2848+
fprintf(stderr, "Option '--st2020-max' requires something equivalent to '--pass st2020'\n");
27902849
return 1;
27912850
}
27922851

@@ -3188,14 +3247,14 @@ int main(int argc, const char** argv)
31883247
if (rdd6_filename) {
31893248
log_warn("Mixing RDD-6 file input and MXF ANC data input not yet supported\n");
31903249
is_enabled = false;
3191-
} else if (pass_anc.empty()) {
3250+
} else if (pass_anc.empty() && strip_anc.empty()) {
31923251
log_warn("Not passing through ANC data track %" PRIszt "\n", i);
31933252
is_enabled = false;
31943253
} else if (have_anc_track) {
31953254
log_warn("Already have an ANC track; not passing through ANC data track %" PRIszt "\n", i);
31963255
is_enabled = false;
31973256
} else {
3198-
if (st436_manifest_count == 0 || filter_anc_manifest(input_data_info, pass_anc)) {
3257+
if (st436_manifest_count == 0 || filter_anc_manifest(input_data_info, pass_anc, strip_anc)) {
31993258
have_anc_track = true;
32003259
} else {
32013260
log_warn("No match found in ANC data manifest; not passing through ANC data track %" PRIszt "\n", i);
@@ -4788,7 +4847,7 @@ int main(int argc, const char** argv)
47884847
}
47894848
else if (input_track_info->essence_type == ANC_DATA)
47904849
{
4791-
write_anc_samples(output_track, frame, pass_anc, anc_buffer);
4850+
write_anc_samples(output_track, frame, pass_anc, strip_anc, anc_buffer);
47924851
}
47934852
else
47944853
{

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ if(NOT BMX_BUILD_LIB_ONLY AND BMX_BUILD_APPS)
2424
add_subdirectory(bmxtranswrap)
2525
add_subdirectory(d10_mxf)
2626
add_subdirectory(d10_qt_klv)
27+
add_subdirectory(filter_anc)
2728
add_subdirectory(growing_file)
2829
add_subdirectory(imf)
2930
add_subdirectory(jpeg2000)

test/filter_anc/.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test.xml.bin text eol=lf

test/filter_anc/CMakeLists.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
include("${CMAKE_CURRENT_SOURCE_DIR}/../testing.cmake")
2+
3+
setup_test_dir("filter_anc")
4+
5+
set(tests
6+
filter_anc_1
7+
filter_anc_2
8+
filter_anc_3
9+
filter_anc_4
10+
filter_anc_5
11+
filter_anc_6
12+
)
13+
14+
foreach(test ${tests})
15+
set(args
16+
"${common_args}"
17+
-P "${CMAKE_CURRENT_SOURCE_DIR}/test_${test}.cmake"
18+
)
19+
setup_test("filter_anc" "bmx_${test}" "${args}")
20+
endforeach()

test/filter_anc/test.xml.bin

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<rdd6 xmlns="http://bbc.co.uk/rd/rdd6/201502">
3+
<first_subframe>
4+
<sync>
5+
<rev_id>0x00</rev_id>
6+
<orig_id>0x01</orig_id>
7+
<orig_addr>0x0000</orig_addr>
8+
<frame_count>3000</frame_count>
9+
</sync>
10+
<dolby_e_complete>
11+
<program_config>5.1</program_config>
12+
<frame_rate>25</frame_rate>
13+
<descr_text>
14+
<program>pr</program>
15+
</descr_text>
16+
</dolby_e_complete>
17+
<dolby_digital_complete_ext_bsi>
18+
<program_id>0</program_id>
19+
<ac_mode>3/2</ac_mode>
20+
<bs_mode>main_complete</bs_mode>
21+
<center_mix_level>-3.0</center_mix_level>
22+
<sur_mix_level>-3.0</sur_mix_level>
23+
<sur_encoded>false</sur_encoded>
24+
<lfe_on>true</lfe_on>
25+
<dialnorm>-23</dialnorm>
26+
<copyright>true</copyright>
27+
<orig_bs>true</orig_bs>
28+
<downmix_mode>lt_rt</downmix_mode>
29+
<lt_rt_center_mix>-3.0</lt_rt_center_mix>
30+
<lt_rt_sur_mix>-3.0</lt_rt_sur_mix>
31+
<lo_ro_center_mix>-3.0</lo_ro_center_mix>
32+
<lo_ro_sur_mix>-3.0</lo_ro_sur_mix>
33+
<ad_conv_type>standard</ad_conv_type>
34+
<hp_filter>true</hp_filter>
35+
<bw_lp_filter>true</bw_lp_filter>
36+
<lfe_lp_filter>true</lfe_lp_filter>
37+
<sur_90_filter>true</sur_90_filter>
38+
<sur_att_filter>true</sur_att_filter>
39+
<rf_preemph_filter>false</rf_preemph_filter>
40+
<compr_pf_1>film_standard</compr_pf_1>
41+
<dyn_range_pf_1>film_standard</dyn_range_pf_1>
42+
<dyn_range_pf_2>none</dyn_range_pf_2>
43+
<dyn_range_pf_3>none</dyn_range_pf_3>
44+
<dyn_range_pf_4>none</dyn_range_pf_4>
45+
</dolby_digital_complete_ext_bsi>
46+
</first_subframe>
47+
<second_subframe>
48+
<sync>
49+
<rev_id>0x00</rev_id>
50+
<orig_id>0x01</orig_id>
51+
<orig_addr>0x0000</orig_addr>
52+
<frame_count>3000</frame_count>
53+
</sync>
54+
<dolby_e_essential>
55+
<program_config>5.1</program_config>
56+
<frame_rate>25</frame_rate>
57+
</dolby_e_essential>
58+
<dolby_digital_essential_ext_bsi>
59+
<program_id>0</program_id>
60+
<ac_mode>3/2</ac_mode>
61+
<bs_mode>main_complete</bs_mode>
62+
<lfe_on>true</lfe_on>
63+
<dialnorm>-23</dialnorm>
64+
<compr_pf_2>film_standard</compr_pf_2>
65+
<dyn_range_pf_5>film_standard</dyn_range_pf_5>
66+
<dyn_range_pf_6>none</dyn_range_pf_6>
67+
<dyn_range_pf_7>none</dyn_range_pf_7>
68+
<dyn_range_pf_8>none</dyn_range_pf_8>
69+
</dolby_digital_essential_ext_bsi>
70+
</second_subframe>
71+
</rdd6>

test/filter_anc/test1.md5

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
a731f871b6aca6e33d8f1ae41e01e977

test/filter_anc/test2.md5

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
d881c256464dcee9507a40db621d2a2d

test/filter_anc/test3.md5

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
d881c256464dcee9507a40db621d2a2d

test/filter_anc/test4.md5

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
a731f871b6aca6e33d8f1ae41e01e977

test/filter_anc/test5.md5

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
d881c256464dcee9507a40db621d2a2d

0 commit comments

Comments
 (0)