blob: c0ffbd34c5e5719e0a4143b0b3e4a650b2e58a8d [file] [log] [blame] [edit]
/*
* Copyright 2023 The ChromiumOS Authors
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef CAMERA_FEATURES_EFFECTS_EFFECTS_METRICS_H_
#define CAMERA_FEATURES_EFFECTS_EFFECTS_METRICS_H_
#include <memory>
#include <utility>
#include <vector>
#include <base/containers/flat_set.h>
#include <base/task/thread_pool.h>
#include <base/time/time.h>
#include "cros-camera/camera_metrics.h"
#include "cros-camera/camera_thread.h"
#include "ml_core/effects_pipeline.h"
namespace cros {
// EffectsMetricsData should be used to collect and aggregate metrics for the
// EffecsStreamManipulator. It is not thread safe, and should only be used from
// the same sequence. The intention is that the client should use the interfaces
// to record metric samples, and then std::move() the instance into the upload
// method of EffectsMetricsUploader and then create a new one.
class EffectsMetricsData {
public:
EffectsMetricsData();
void RecordSelectedEffect(const EffectsConfig& config);
void RecordFrameProcessingLatency(const EffectsConfig& config,
CameraEffectStreamType stream_type,
const base::TimeDelta& latency);
void RecordFrameProcessingInterval(const EffectsConfig& config,
CameraEffectStreamType stream_type,
const base::TimeDelta& interval);
void RecordRequestedFrameRate(int fps);
void RecordStreamSize(CameraEffectStreamType stream_type, size_t size);
void RecordNumConcurrentStreams(size_t num_concurrent_streams);
void RecordNumConcurrentProcessedStreams(
size_t num_concurrent_processed_streams);
void RecordStillShotTaken();
void RecordError(CameraEffectError error);
bool EffectSelected(CameraEffect effect) const;
base::TimeDelta AverageFrameProcessingLatency(
CameraEffect effect, CameraEffectStreamType stream_type) const;
base::TimeDelta AverageFrameProcessingInterval(
CameraEffect effect, CameraEffectStreamType stream_type) const;
private:
friend class EffectsMetricsUploader;
int max_requested_fps_ = 0;
size_t max_num_concurrent_streams_ = 0u;
size_t max_num_concurrent_processed_streams_ = 0u;
size_t num_still_shots_taken_ = 0;
CameraEffectError error_ = CameraEffectError::kNoError;
base::flat_set<CameraEffect> selected_effects_;
// A vector of time durations for each effect and stream type combination.
using DurationVectorArray = std::array<
std::array<std::vector<base::TimeDelta>,
static_cast<size_t>(CameraEffectStreamType::kMaxValue) + 1>,
static_cast<size_t>(CameraEffect::kMaxValue) + 1>;
DurationVectorArray processing_times_;
DurationVectorArray frame_intervals_;
std::array<std::pair<size_t /*min*/, size_t /*max*/>,
static_cast<size_t>(CameraEffect::kMaxValue) + 1>
stream_sizes_;
};
// EffectsMetricsUploader will upload an instance of EffectsMetricsData to
// UMA. It is thread-safe. The UploadMetricsData call will
// consume an EffectsMetricsData instance and post it asynchronously via the
// task_runner provided on construction.
class EffectsMetricsUploader {
public:
explicit EffectsMetricsUploader(
scoped_refptr<base::SequencedTaskRunner> task_runner);
base::TimeDelta TimeSinceLastUpload();
void UploadMetricsData(EffectsMetricsData metrics);
private:
base::Lock lock_;
void UploadMetricsDataOnThread(EffectsMetricsData metrics);
std::unique_ptr<CameraMetrics> metrics_helper_;
base::TimeTicks last_upload_time_ GUARDED_BY(lock_);
scoped_refptr<base::SequencedTaskRunner> task_runner_;
};
} // namespace cros
#endif // CAMERA_FEATURES_EFFECTS_EFFECTS_METRICS_H_