blob: c1e560baa3e6afbc66942a3ae20a896ff34341c1 [file] [log] [blame]
// Copyright 2022 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef STARBOARD_SHARED_STARBOARD_MEDIA_MIME_SUPPORTABILITY_CACHE_H_
#define STARBOARD_SHARED_STARBOARD_MEDIA_MIME_SUPPORTABILITY_CACHE_H_
#include <atomic>
#include <queue>
#include <string>
#include <unordered_map>
#include "starboard/common/mutex.h"
#include "starboard/shared/internal_only.h"
#include "starboard/shared/starboard/media/parsed_mime_info.h"
namespace starboard {
namespace shared {
namespace starboard {
namespace media {
typedef enum Supportability {
kSupportabilityUnknown,
kSupportabilitySupported,
kSupportabilityNotSupported,
} Supportability;
// MimeSupportabilityCache caches the supportabilities of raw mime strings.
// To increase cache hit rate, it strips bitrate from the raw mime string, and
// stores a supported bitrate range for mime strings with same other attributes.
//
// Note: MimeSupportabilityCache leverage the assumption that if the
// platform can support a codec with bitrate of n, the codec should also support
// any bitrate less than n. If that assumption is not true, please do NOT enable
// MimeSupportabilityCache.
//
// Note: anytime the platform codec capabilities have changed, please call
// MimeSupportabilityCache::ClearCachedMimeSupportabilities() to clear the
// outdated results.
//
// TODO: add unit tests for MimeSupportabilityCache.
class MimeSupportabilityCache {
public:
static MimeSupportabilityCache* GetInstance();
// When cache is not enabled, GetMimeSupportability() will return cached
// ParsedMimeInfo with kSupportabilityUnknown, and CacheMimeSupportability()
// will do nothing.
bool IsEnabled() const { return is_enabled_; }
void SetCacheEnabled(bool enabled) { is_enabled_ = enabled; }
// Set the max number of the cached ParsedMimeInfos and its supportabilities.
void SetCacheMaxSize(size_t size) { max_size_ = size; }
// Get cached ParsedMimeInfo and mime supportability. If there's no cached
// ParsedMimeInfo, it will parse the mime string and cache the result.
// If we cannot get a valid ParsedMimeInfo from |mime|,
// GetMimeSupportability() will return kSupportabilityNotSupported with an
// invalid ParsedMimeInfo. Ideally, we should decouple mime parsing and
// supportability cache, but considering that the cache is only for internal
// use, to avoid repeated lookups, we do parsing in this function for now.
// Note that |mime| and |mime_info| cannot be null.
Supportability GetMimeSupportability(const char* mime,
ParsedMimeInfo* mime_info);
// Update cached supportability of the mime string.
// Note that if |supportability| is kSupportabilityUnknown or we cannot
// get a valid ParsedMimeInfo from |mime|, CacheMimeSupportability()
// will not cache the supportability.
void CacheMimeSupportability(const char* mime, Supportability supportability);
// Clear all cached supportabilities. But it will not remove cached
// ParsedMimeInfos, as for the same mime string, the parsed results should be
// always the same.
void ClearCachedMimeSupportabilities();
void DumpCache();
private:
const int kDefaultCacheMaxSize = 2000;
struct Entry {
ParsedMimeInfo mime_info;
int max_supported_bitrate = -1;
int min_unsupported_bitrate = INT_MAX;
explicit Entry(const std::string& mime) : mime_info(mime) {}
};
// Class can only be instanced via the singleton
MimeSupportabilityCache() {}
~MimeSupportabilityCache() {}
MimeSupportabilityCache(const MimeSupportabilityCache&) = delete;
MimeSupportabilityCache& operator=(const MimeSupportabilityCache&) = delete;
Entry& GetEntry_Locked(const std::string& mime_string);
Supportability IsBitrateSupported_Locked(const Entry& entry,
int bitrate) const;
void UpdateBitrateSupportability_Locked(Entry* entry,
int bitrate,
Supportability supportability);
typedef std::unordered_map<std::string, Entry> Entries;
Mutex mutex_;
Entries entries_;
std::queue<Entries::iterator> fifo_queue_;
std::atomic_int max_size_{kDefaultCacheMaxSize};
std::atomic_bool is_enabled_{false};
};
} // namespace media
} // namespace starboard
} // namespace shared
} // namespace starboard
#endif // STARBOARD_SHARED_STARBOARD_MEDIA_MIME_SUPPORTABILITY_CACHE_H_