我正在编写一个Android应用程序,使用视频输出上的镜像功能来测量电视上的显示延迟。经过多次修改后,我的代码变得太复杂了,所以我抓了它并进行了重写。我的问题是它的表现不如预期。方块没有闪烁,时间为0.0,评级非常好。我已经测试过通过线程改变ui,使方形变成不同的颜色,这很好。有人可以告诉我这是什么问题以及如何解决它?应用程序的工作方式是将设备挂钩到电视机上,它会反映显示屏。然后它改变应用程序中正方形的颜色并给出一个时间戳,然后它等到相机检测到更改然后再给另一个时间戳。使用两个时间戳你可以弄清楚电视的延迟。我把它放在一个循环中因为相机只能以15ish fps捕获,所以我需要多次运行测试才能得到准确的结果。问题是它总是显示为0.0ms,这是一个不可能的数字,因为大多数消费者电视的延迟是9ms。我从每个相机帧中获取RGB值。
class lagTestThread extends Thread {
@Override
public void run () {
long lagStartTime;
long lagEndTime;
long tempResult;
final double rating;
int x;
long testResult = 0;
int cnt;
for (cnt = 0; cnt >= 100; cnt++){
runOnUiThread(new Runnable() {
@Override
public void run() {
lagSquare.setBackgroundColor(Color.rgb(000, 000, 000));
}
});
while (redVal >= 10.0 && blueVal >= 10.0 && greenVal >= 10.0) {
x = 0;
}
redVal = 0;
blueVal = 0;
greenVal = 0;
lagStartTime = System.nanoTime(); //start lagTimer start
runOnUiThread(new Runnable() {
@Override
public void run() {
lagSquare.setBackgroundColor(Color.rgb(255, 255, 255));
}
});
while (redVal <= 100.0 && blueVal <= 100.0 && greenVal <= 100.0) {
x = 0;
}
lagEndTime = System.nanoTime(); //start lagTimer end
runOnUiThread(new Runnable() {
@Override
public void run() {
lagSquare.setBackgroundColor(Color.rgb(000, 000, 000));
}
});
tempResult = (lagEndTime - lagStartTime);
if (tempResult <= testResult && tempResult != 0) {
testResult = tempResult;
}
}
rating = ((double) testResult) / 1000000.0;
final String finalResultString = String.valueOf(rating);
runOnUiThread(new Runnable() {
@Override
public void run() {
lagTime.setText(finalResultString);
if (rating <= 17.0) {
lagRating.setText("Excellent");
} else if (rating <= 34.0) {
lagRating.setText("Great");
} else if (rating <= 51.0) {
lagRating.setText("Average");
} else {
lagRating.setText("Bad");
}
}
});
}
}
我称之为
public void startTest(View view) {
lagTestThread lagTest = new lagTestThread();
lagTest.start();
}
redVal,blueVal,greenVal声明
@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
double[] rgb = inputFrame.rgba().get(100, 100);
redVal = rgb[0];
blueVal = rgb[2];
greenVal = rgb[1];
Log.i("", "red:" + rgb[0] + " green:" + rgb[1] + " blue:" + rgb[2]);
return rgbMat;
}
答案 0 :(得分:1)
runOnUiThread()
导致Runnable 发布到UI线程,此时函数立即返回。 Runnable稍后会执行。
您的代码将事件发布到UI线程并检查系统时间,这意味着您需要计算将事件发布到UI线程所需的时间,而不是计算它们运行所需的时间。此外,由于所有事件都排在一起,因此很可能它们都会在同一帧中执行,因此您只会看到上次setBackgroundColor()
来电的结果。
如果您真的想要从UI线程中分离显示和计时代码,您应该考虑使用SurfaceView进行此操作,可以独立于UI线程进行更新。 (SurfaceView的缺点是使用它比使用自定义视图要复杂得多。)