video_decode_stats_db_impl.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef MEDIA_CAPABILITIES_VIDEO_DECODE_STATS_DB_IMPL_H_
  5. #define MEDIA_CAPABILITIES_VIDEO_DECODE_STATS_DB_IMPL_H_
  6. #include <memory>
  7. #include "base/files/file_path.h"
  8. #include "base/memory/raw_ptr.h"
  9. #include "base/memory/weak_ptr.h"
  10. #include "base/metrics/field_trial_params.h"
  11. #include "base/time/time.h"
  12. #include "components/leveldb_proto/public/proto_database.h"
  13. #include "media/base/media_export.h"
  14. #include "media/base/video_codecs.h"
  15. #include "media/capabilities/pending_operations.h"
  16. #include "media/capabilities/video_decode_stats_db.h"
  17. #include "ui/gfx/geometry/size.h"
  18. namespace base {
  19. class FilePath;
  20. class Clock;
  21. } // namespace base
  22. namespace leveldb_proto {
  23. class ProtoDatabaseProvider;
  24. } // namespace leveldb_proto
  25. namespace media {
  26. class DecodeStatsProto;
  27. // LevelDB implementation of VideoDecodeStatsDB. This class is not
  28. // thread safe. All API calls should happen on the same sequence used for
  29. // construction. API callbacks will also occur on this sequence.
  30. class MEDIA_EXPORT VideoDecodeStatsDBImpl : public VideoDecodeStatsDB {
  31. public:
  32. static const char kMaxFramesPerBufferParamName[];
  33. static const char kMaxDaysToKeepStatsParamName[];
  34. static const char kEnableUnweightedEntriesParamName[];
  35. // Create an instance! |db_dir| specifies where to store LevelDB files to
  36. // disk. LevelDB generates a handful of files, so its recommended to provide a
  37. // dedicated directory to keep them isolated.
  38. static std::unique_ptr<VideoDecodeStatsDBImpl> Create(
  39. base::FilePath db_dir,
  40. leveldb_proto::ProtoDatabaseProvider* db_provider);
  41. VideoDecodeStatsDBImpl(const VideoDecodeStatsDBImpl&) = delete;
  42. VideoDecodeStatsDBImpl& operator=(const VideoDecodeStatsDBImpl&) = delete;
  43. ~VideoDecodeStatsDBImpl() override;
  44. // Implement VideoDecodeStatsDB.
  45. void Initialize(InitializeCB init_cb) override;
  46. void AppendDecodeStats(const VideoDescKey& key,
  47. const DecodeStatsEntry& entry,
  48. AppendDecodeStatsCB append_done_cb) override;
  49. void GetDecodeStats(const VideoDescKey& key,
  50. GetDecodeStatsCB get_stats_cb) override;
  51. void ClearStats(base::OnceClosure clear_done_cb) override;
  52. private:
  53. friend class VideoDecodeStatsDBImplTest;
  54. // Private constructor only called by tests (friends). Production code
  55. // should always use the static Create() method.
  56. VideoDecodeStatsDBImpl(
  57. std::unique_ptr<leveldb_proto::ProtoDatabase<DecodeStatsProto>> db);
  58. // Default |last_write_time| for DB entries that lack a time stamp due to
  59. // using an earlier version of DecodeStatsProto. Date chosen so old stats from
  60. // previous version will expire (unless new stats arrive) roughly 2 months
  61. // after the proto update hits the chrome Stable channel (M71).
  62. static constexpr char kDefaultWriteTime[] = "01-FEB-2019 12:00pm";
  63. // Number of decoded frames to keep in the rolling "window" for a given entry
  64. // in the database.
  65. static int GetMaxFramesPerBuffer();
  66. // Number of days after which stats will be discarded if not updated. This
  67. // avoids users getting stuck with a bad capability prediction that may have
  68. // been due to one-off circumstances.
  69. static int GetMaxDaysToKeepStats();
  70. // When true, each playback entry in the DB should be given equal weight
  71. // regardless of how many frames were decoded.
  72. static bool GetEnableUnweightedEntries();
  73. // Returns current feature params.
  74. static base::FieldTrialParams GetFieldTrialParams();
  75. // Called when the database has been initialized. Will immediately call
  76. // |init_cb| to forward |success|.
  77. void OnInit(PendingOperations::Id id,
  78. InitializeCB init_cb,
  79. leveldb_proto::Enums::InitStatus status);
  80. // Returns true if the DB is successfully initialized.
  81. bool IsInitialized();
  82. // Passed as the callback for |OnGotDecodeStats| by |AppendDecodeStats| to
  83. // update the database once we've read the existing stats entry.
  84. void WriteUpdatedEntry(PendingOperations::Id op_id,
  85. const VideoDescKey& key,
  86. const DecodeStatsEntry& entry,
  87. AppendDecodeStatsCB append_done_cb,
  88. bool read_success,
  89. std::unique_ptr<DecodeStatsProto> stats_proto);
  90. // Called when the database has been modified after a call to
  91. // |WriteUpdatedEntry|. Will run |append_done_cb| when done.
  92. void OnEntryUpdated(PendingOperations::Id op_id,
  93. AppendDecodeStatsCB append_done_cb,
  94. bool success);
  95. // Called when GetDecodeStats() operation was performed. |get_stats_cb|
  96. // will be run with |success| and a |DecodeStatsEntry| created from
  97. // |stats_proto| or nullptr if no entry was found for the requested key.
  98. void OnGotDecodeStats(PendingOperations::Id op_id,
  99. GetDecodeStatsCB get_stats_cb,
  100. bool success,
  101. std::unique_ptr<DecodeStatsProto> stats_proto);
  102. // Internal callback for OnLoadAllKeysForClearing(), initially triggered by
  103. // ClearStats(). Method simply logs |success| and runs |clear_done_cb|.
  104. void OnStatsCleared(PendingOperations::Id op_id,
  105. base::OnceClosure clear_done_cb,
  106. bool success);
  107. // Return true if:
  108. // values aren't corrupted nonsense (e.g. way more frames dropped than
  109. // decoded, or number of frames_decoded < frames_power_efficient)
  110. // &&
  111. // stats aren't expired.
  112. // ("now" - stats_proto.last_write_date > GeMaxDaysToKeepStats())
  113. bool AreStatsUsable(const DecodeStatsProto* const stats_proto);
  114. void set_wall_clock_for_test(const base::Clock* tick_clock) {
  115. wall_clock_ = tick_clock;
  116. }
  117. PendingOperations pending_operations_;
  118. // Indicates whether initialization is completed. Does not indicate whether it
  119. // was successful. Will be reset upon calling DestroyStats(). Failed
  120. // initialization is signaled by setting |db_| to null.
  121. bool db_init_ = false;
  122. // ProtoDatabase instance. Set to nullptr if fatal database error is
  123. // encountered.
  124. std::unique_ptr<leveldb_proto::ProtoDatabase<DecodeStatsProto>> db_;
  125. // For getting wall-clock time. Tests may override via SetClockForTest().
  126. raw_ptr<const base::Clock> wall_clock_ = nullptr;
  127. // Stores parsed value of |kDefaultWriteTime|.
  128. base::Time default_write_time_;
  129. // Ensures all access to class members come on the same sequence. API calls
  130. // and callbacks should occur on the same sequence used during construction.
  131. // LevelDB operations happen on a separate task runner, but all LevelDB
  132. // callbacks to this happen on the checked sequence.
  133. SEQUENCE_CHECKER(sequence_checker_);
  134. base::WeakPtrFactory<VideoDecodeStatsDBImpl> weak_ptr_factory_{this};
  135. };
  136. } // namespace media
  137. #endif // MEDIA_CAPABILITIES_VIDEO_DECODE_STATS_DB_IMPL_H_