|
60 | 60 | import com.googleresearch.capturesync.softwaresync.CSVLogger;
|
61 | 61 | import com.googleresearch.capturesync.softwaresync.SoftwareSyncLeader;
|
62 | 62 | import com.googleresearch.capturesync.softwaresync.TimeUtils;
|
| 63 | +import com.googleresearch.capturesync.softwaresync.phasealign.PeriodCalculator; |
63 | 64 | import com.googleresearch.capturesync.softwaresync.phasealign.PhaseConfig;
|
64 | 65 |
|
65 | 66 | import java.io.File;
|
|
77 | 78 | import java.util.Date;
|
78 | 79 | import java.util.List;
|
79 | 80 | import java.util.Locale;
|
| 81 | +import java.util.concurrent.Future; |
| 82 | +import java.util.concurrent.FutureTask; |
80 | 83 | import java.util.stream.Collectors;
|
81 | 84 |
|
82 | 85 | import org.json.JSONException;
|
83 | 86 | import org.json.JSONObject;
|
84 | 87 |
|
85 |
| -/** Main activity for the libsoftwaresync demo app using the camera 2 API. */ |
| 88 | +/** |
| 89 | + * Main activity for the libsoftwaresync demo app using the camera 2 API. |
| 90 | + */ |
86 | 91 | public class MainActivity extends Activity {
|
87 | 92 | private static final String TAG = "MainActivity";
|
88 | 93 | // private static final int EXP_LEN = 20_000;
|
89 | 94 | private static final int STATIC_LEN = 15_000;
|
90 | 95 | private String lastTimeStamp;
|
| 96 | + private PeriodCalculator periodCalculator; |
91 | 97 |
|
92 | 98 | public Integer getLastVideoSeqId() {
|
93 | 99 | return lastVideoSeqId;
|
94 | 100 | }
|
95 | 101 |
|
96 | 102 | private Integer lastVideoSeqId;
|
| 103 | + |
97 | 104 | public int getCurSequence() {
|
98 | 105 | return curSequence;
|
99 | 106 | }
|
@@ -144,6 +151,7 @@ public MediaRecorder getMediaRecorder() {
|
144 | 151 |
|
145 | 152 | // UI controls.
|
146 | 153 | private Button captureStillButton;
|
| 154 | + private Button getPeriodButton; |
147 | 155 | private Button phaseAlignButton;
|
148 | 156 | private SeekBar exposureSeekBar;
|
149 | 157 | private SeekBar sensitivitySeekBar;
|
@@ -200,7 +208,7 @@ public void surfaceDestroyed(SurfaceHolder holder) {
|
200 | 208 | protected void onCreate(Bundle savedInstanceState) {
|
201 | 209 | super.onCreate(savedInstanceState);
|
202 | 210 | Log.v(TAG, "onCreate");
|
203 |
| - |
| 211 | + periodCalculator = new PeriodCalculator(); |
204 | 212 | checkPermissions();
|
205 | 213 | if (permissionsGranted) {
|
206 | 214 | onCreateWithPermission();
|
@@ -263,7 +271,9 @@ private void maybeUpdateConfiguration(Configuration newConfig) {
|
263 | 271 | }
|
264 | 272 | }
|
265 | 273 |
|
266 |
| - /** Resize the SurfaceView to be centered on screen. */ |
| 274 | + /** |
| 275 | + * Resize the SurfaceView to be centered on screen. |
| 276 | + */ |
267 | 277 | private void updateViewfinderLayoutParams() {
|
268 | 278 | FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) surfaceView.getLayoutParams();
|
269 | 279 |
|
@@ -363,12 +373,17 @@ public void onError(CameraDevice cameraDevice, int i) {
|
363 | 373 | }
|
364 | 374 | }
|
365 | 375 |
|
| 376 | + public void onTimestampNs(long timestampNs) { |
| 377 | + periodCalculator.onFrameTimestamp(timestampNs); |
| 378 | + } |
| 379 | + |
366 | 380 | /* Set up UI controls and listeners based on if device is currently a leader of client. */
|
367 | 381 | private void setLeaderClientControls(boolean isLeader) {
|
368 | 382 | if (isLeader) {
|
369 | 383 | // Leader, all controls visible and set.
|
370 | 384 | captureStillButton.setVisibility(View.VISIBLE);
|
371 | 385 | phaseAlignButton.setVisibility(View.VISIBLE);
|
| 386 | + getPeriodButton.setVisibility(View.VISIBLE); |
372 | 387 | exposureSeekBar.setVisibility(View.VISIBLE);
|
373 | 388 | sensitivitySeekBar.setVisibility(View.VISIBLE);
|
374 | 389 |
|
@@ -415,6 +430,26 @@ private void setLeaderClientControls(boolean isLeader) {
|
415 | 430 | String.valueOf(futureTimestamp));*/
|
416 | 431 | });
|
417 | 432 |
|
| 433 | + getPeriodButton.setOnClickListener( |
| 434 | + view -> { |
| 435 | + Log.d(TAG, "Calculating frames period."); |
| 436 | + |
| 437 | + FutureTask<Integer> periodTask = new FutureTask<Integer>( |
| 438 | + () -> { |
| 439 | + try { |
| 440 | + long periodNs = periodCalculator.getPeriodNs(); |
| 441 | + Log.d(TAG, "Calculated period: " + periodNs); |
| 442 | + phaseAlignController.setPeriodNs(periodNs); |
| 443 | + } catch (InterruptedException e) { |
| 444 | + Log.d(TAG, "Failed calculating period"); |
| 445 | + e.printStackTrace(); |
| 446 | + } |
| 447 | + return 0; |
| 448 | + } |
| 449 | + ); |
| 450 | + periodTask.run(); |
| 451 | + } |
| 452 | + ); |
418 | 453 |
|
419 | 454 | phaseAlignButton.setOnClickListener(
|
420 | 455 | view -> {
|
@@ -486,6 +521,7 @@ public void onStopTrackingTouch(SeekBar seekBar) {
|
486 | 521 | // Client. All controls invisible.
|
487 | 522 | captureStillButton.setVisibility(View.INVISIBLE);
|
488 | 523 | phaseAlignButton.setVisibility(View.INVISIBLE);
|
| 524 | + getPeriodButton.setVisibility(View.INVISIBLE); |
489 | 525 | exposureSeekBar.setVisibility(View.INVISIBLE);
|
490 | 526 | sensitivitySeekBar.setVisibility(View.INVISIBLE);
|
491 | 527 |
|
@@ -662,7 +698,9 @@ public void notifyCaptured(String name) {
|
662 | 698 | });
|
663 | 699 | }
|
664 | 700 |
|
665 |
| - /** Compares two {@code Size}s based on their areas. */ |
| 701 | + /** |
| 702 | + * Compares two {@code Size}s based on their areas. |
| 703 | + */ |
666 | 704 | static class CompareSizesByArea implements Comparator<Size> {
|
667 | 705 |
|
668 | 706 | @Override
|
@@ -707,6 +745,8 @@ private void createUi() {
|
707 | 745 | // Controls.
|
708 | 746 | captureStillButton = findViewById(R.id.capture_still_button);
|
709 | 747 | phaseAlignButton = findViewById(R.id.phase_align_button);
|
| 748 | + getPeriodButton = findViewById(R.id.get_period_button); |
| 749 | + |
710 | 750 | exposureSeekBar = findViewById(R.id.exposure_seekbar);
|
711 | 751 | sensitivitySeekBar = findViewById(R.id.sensitivity_seekbar);
|
712 | 752 | sensorExposureTextView.setText("Exposure: " + prettyExposureValue(currentSensorExposureTimeNs));
|
@@ -781,7 +821,9 @@ public void onWindowFocusChanged(boolean hasFocus) {
|
781 | 821 | }
|
782 | 822 | }
|
783 | 823 |
|
784 |
| - /** Create {@link #cameraController}, and subscribe to status change events. */ |
| 824 | + /** |
| 825 | + * Create {@link #cameraController}, and subscribe to status change events. |
| 826 | + */ |
785 | 827 | private void initCameraController() {
|
786 | 828 | cameraController =
|
787 | 829 | new CameraController(
|
@@ -1034,7 +1076,9 @@ private void checkPermissions() {
|
1034 | 1076 | }
|
1035 | 1077 | }
|
1036 | 1078 |
|
1037 |
| - /** Wait for permissions to continue onCreate. */ |
| 1079 | + /** |
| 1080 | + * Wait for permissions to continue onCreate. |
| 1081 | + */ |
1038 | 1082 | @Override
|
1039 | 1083 | public void onRequestPermissionsResult(
|
1040 | 1084 | int requestCode, String[] permissions, int[] grantResults) {
|
|
0 commit comments