aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Fjeldtvedt <jaffe1@gmail.com>2016-07-22 14:24:47 +0200
committerHans Verkuil <hans.verkuil@cisco.com>2016-07-22 14:27:32 +0200
commit1e31eadf1fe4d0408224121b9decf37bafdb5591 (patch)
tree30260d72d969b4da60afa657d288ffbe6c2bada8
parent166bdd14db919543763b10a59bed346e390762ff (diff)
add test for Audio Rate Control
This adds a new test for the Audio Rate Control, with a subtest for the Set Audio Rate message. The follower is extended to accept this message if its own Set Audio Rate bit is set, otherwise it Feature Aborts. Device features are now probed for during the topolgy scan, since those are needed by multiple tests. Signed-off-by: Johan Fjeldtvedt <jaffe1@gmail.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
-rw-r--r--utils/cec-compliance/cec-compliance.cpp24
-rw-r--r--utils/cec-compliance/cec-compliance.h3
-rw-r--r--utils/cec-compliance/cec-test-audio.cpp28
-rw-r--r--utils/cec-compliance/cec-test.cpp11
-rw-r--r--utils/cec-follower/cec-follower.cpp5
-rw-r--r--utils/cec-follower/cec-follower.h1
-rw-r--r--utils/cec-follower/cec-processing.cpp8
7 files changed, 74 insertions, 6 deletions
diff --git a/utils/cec-compliance/cec-compliance.cpp b/utils/cec-compliance/cec-compliance.cpp
index ae75c6be..93cbc1ce 100644
--- a/utils/cec-compliance/cec-compliance.cpp
+++ b/utils/cec-compliance/cec-compliance.cpp
@@ -769,6 +769,30 @@ static void topology_probe_device(struct node *node, unsigned i, unsigned la)
printf("%s\n", power_status2s(pwr));
}
}
+
+ if (node->remote[i].cec_version < CEC_OP_CEC_VERSION_2_0)
+ return;
+ cec_msg_init(&msg, la, i);
+ cec_msg_give_features(&msg, true);
+ if (transmit_timeout(node, &msg) && !timed_out_or_abort(&msg)) {
+ /* RC Profile and Device Features are assumed to be 1 byte. As of CEC 2.0 only
+ 1 byte is used, but this might be extended in future versions. */
+ __u8 cec_version, all_device_types;
+ const __u8 *rc_profile, *dev_features;
+
+ cec_ops_report_features(&msg, &cec_version, &all_device_types,
+ &rc_profile, &dev_features);
+ if (rc_profile == NULL || dev_features == NULL)
+ return;
+ node->remote[i].rc_profile = *rc_profile;
+ node->remote[i].dev_features = *dev_features;
+ node->remote[i].has_arc_rx =
+ (*dev_features & CEC_OP_FEAT_DEV_SOURCE_HAS_ARC_RX) != 0;
+ node->remote[i].has_arc_tx =
+ (*dev_features & CEC_OP_FEAT_DEV_SINK_HAS_ARC_TX) != 0;
+ node->remote[i].has_aud_rate =
+ (*dev_features & CEC_OP_FEAT_DEV_HAS_SET_AUDIO_RATE) != 0;
+ }
}
int main(int argc, char **argv)
diff --git a/utils/cec-compliance/cec-compliance.h b/utils/cec-compliance/cec-compliance.h
index cd6f39be..9762bb70 100644
--- a/utils/cec-compliance/cec-compliance.h
+++ b/utils/cec-compliance/cec-compliance.h
@@ -144,6 +144,7 @@ struct remote {
__u8 supp_format_code;
__u8 volume;
__u8 mute;
+ bool has_aud_rate;
};
struct node {
@@ -369,6 +370,8 @@ extern struct remote_subtest dal_subtests[];
extern const unsigned dal_subtests_size;
extern struct remote_subtest arc_subtests[];
extern const unsigned arc_subtests_size;
+extern struct remote_subtest audio_rate_ctl_subtests[];
+extern const unsigned audio_rate_ctl_subtests_size;
// cec-power.cpp
bool util_interactive_ensure_power_state(struct node *node, unsigned me, unsigned la, bool interactive,
diff --git a/utils/cec-compliance/cec-test-audio.cpp b/utils/cec-compliance/cec-test-audio.cpp
index 0915261e..f6adf09b 100644
--- a/utils/cec-compliance/cec-test-audio.cpp
+++ b/utils/cec-compliance/cec-test-audio.cpp
@@ -719,3 +719,31 @@ struct remote_subtest sac_subtests[] = {
};
const unsigned sac_subtests_size = ARRAY_SIZE(sac_subtests);
+
+
+/* Audio Rate Control */
+
+static int audio_rate_ctl_set_audio_rate(struct node *node, unsigned me, unsigned la, bool interactive)
+{
+ struct cec_msg msg = {};
+
+ cec_msg_init(&msg, me, la);
+ cec_msg_set_audio_rate(&msg, CEC_OP_AUD_RATE_WIDE_STD);
+ fail_on_test(!transmit_timeout(node, &msg));
+ /* CEC 2.0: Devices shall use the device feature bit to indicate support. */
+ fail_on_test_v2(node->remote[la].cec_version, node->remote[la].has_aud_rate &&
+ cec_msg_status_is_abort(&msg));
+ fail_on_test_v2(node->remote[la].cec_version, !node->remote[la].has_aud_rate);
+ if (cec_msg_status_is_abort(&msg))
+ return NOTSUPPORTED;
+
+ return 0;
+}
+
+struct remote_subtest audio_rate_ctl_subtests[] = {
+ { "Set Audio Rate",
+ CEC_LOG_ADDR_MASK_PLAYBACK | CEC_LOG_ADDR_MASK_RECORD | CEC_LOG_ADDR_MASK_TUNER,
+ audio_rate_ctl_set_audio_rate },
+};
+
+const unsigned audio_rate_ctl_subtests_size = ARRAY_SIZE(audio_rate_ctl_subtests);
diff --git a/utils/cec-compliance/cec-test.cpp b/utils/cec-compliance/cec-test.cpp
index d7fd11f0..ab354ee7 100644
--- a/utils/cec-compliance/cec-test.cpp
+++ b/utils/cec-compliance/cec-test.cpp
@@ -148,14 +148,14 @@ static int system_info_give_features(struct node *node, unsigned me, unsigned la
cec_ops_report_features(&msg, &cec_version, &all_device_types, &rc_profile, &dev_features);
fail_on_test(cec_version != node->remote[la].cec_version);
fail_on_test(rc_profile == NULL || dev_features == NULL);
- node->remote[la].rc_profile = *rc_profile;
- node->remote[la].dev_features = *dev_features;
- node->remote[la].has_arc_rx = (*dev_features & CEC_OP_FEAT_DEV_SOURCE_HAS_ARC_RX) != 0;
- node->remote[la].has_arc_tx = (*dev_features & CEC_OP_FEAT_DEV_SINK_HAS_ARC_TX) != 0;
info("All Device Types: \t\t%s\n", all_dev_types2s(all_device_types).c_str());
info("RC Profile: \t%s", rc_src_prof2s(*rc_profile).c_str());
info("Device Features: \t%s", dev_feat2s(*dev_features).c_str());
+ if (!(cec_has_playback(1 << la) || cec_has_record(1 << la) || cec_has_tuner(1 << la)) &&
+ node->remote[la].has_aud_rate) {
+ return fail("Only Playback, Recording or Tuner devices shall set the Set Audio Rate bit");
+ }
return 0;
}
@@ -547,6 +547,9 @@ static struct remote_test tests[] = {
test_case_ext("System Audio Control feature",
TAG_SYSTEM_AUDIO_CONTROL,
sac_subtests),
+ test_case_ext("Audio Rate Control feature",
+ TAG_AUDIO_RATE_CONTROL,
+ audio_rate_ctl_subtests),
test_case_ext("One Touch Play feature",
TAG_ONE_TOUCH_PLAY,
one_touch_play_subtests),
diff --git a/utils/cec-follower/cec-follower.cpp b/utils/cec-follower/cec-follower.cpp
index dd0f60f7..7fb566a7 100644
--- a/utils/cec-follower/cec-follower.cpp
+++ b/utils/cec-follower/cec-follower.cpp
@@ -700,8 +700,9 @@ int main(int argc, char **argv)
printf("\t RC TV Profile : %s\n", s);
}
} else {
- node.has_arc_rx = ((byte & CEC_OP_FEAT_DEV_SOURCE_HAS_ARC_RX) != 0);
- node.has_arc_tx = ((byte & CEC_OP_FEAT_DEV_SINK_HAS_ARC_TX) != 0);
+ node.has_arc_rx = (byte & CEC_OP_FEAT_DEV_SOURCE_HAS_ARC_RX) != 0;
+ node.has_arc_tx = (byte & CEC_OP_FEAT_DEV_SINK_HAS_ARC_TX) != 0;
+ node.has_aud_rate = (byte & CEC_OP_FEAT_DEV_HAS_SET_AUDIO_RATE) != 0;
printf("\t Device Features :\n%s",
dev_feat2s(byte).c_str());
}
diff --git a/utils/cec-follower/cec-follower.h b/utils/cec-follower/cec-follower.h
index 4fb37148..e68f1fa6 100644
--- a/utils/cec-follower/cec-follower.h
+++ b/utils/cec-follower/cec-follower.h
@@ -68,6 +68,7 @@ struct node {
__u16 phys_addr;
bool has_arc_rx;
bool has_arc_tx;
+ bool has_aud_rate;
};
struct la_info {
diff --git a/utils/cec-follower/cec-processing.cpp b/utils/cec-follower/cec-processing.cpp
index 5d6c6d35..b1daf692 100644
--- a/utils/cec-follower/cec-processing.cpp
+++ b/utils/cec-follower/cec-processing.cpp
@@ -686,6 +686,14 @@ static void processMsg(struct node *node, struct cec_msg &msg, unsigned me)
return;
+ /* Audio Rate Control */
+
+ case CEC_MSG_SET_AUDIO_RATE:
+ if (node->has_aud_rate)
+ return;
+ break;
+
+
/* Core */
case CEC_MSG_FEATURE_ABORT:

Privacy Policy