OEMCrypto Profiler - Merge of Widevine Updates
This change is a merge of the following changes: 1. Remove MultipleSessions (go/wvgerrit/16763) 2. Increase Memory Budget (go/wvgerrit/16764) 3. Fixing Possible Integer Overflow (go/wvgerrit/16765) 4. Creating Call Table (go/wvgerrit/16766) 5. Creating Call History (go/wvgerrit/16767) 6. Connecting Profiled Scope (go/wvgerrit/16768) 7. Adding Call Table Version Number (go/wvgerrit/16780) 8. Add Version Number to Call History (go/wvgerrit/16781) bug: 27157796 Change-Id: Ia3f088a1714f3f5b426fee6141daa4ea8d832cf4
This commit is contained in:
170
libwvdrmengine/cdm/profiler/src/call_history.cpp
Normal file
170
libwvdrmengine/cdm/profiler/src/call_history.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
|
||||
#include "call_history.h"
|
||||
|
||||
#include <log.h>
|
||||
|
||||
#include "entry_writer.h"
|
||||
|
||||
namespace wvcdm {
|
||||
namespace oemprofiler {
|
||||
|
||||
namespace {
|
||||
const size_t kProfilingMemoryBudget = 64 * 1024; // 64 KB
|
||||
const uint8_t kOutputVersionNumber = 0x00;
|
||||
}
|
||||
|
||||
CallHistory::CallHistory() :
|
||||
buffer_(kProfilingMemoryBudget),
|
||||
time_at_head_(0),
|
||||
time_at_tail_(0) {
|
||||
|
||||
}
|
||||
|
||||
void CallHistory::Write(
|
||||
OEM_FUNCTION fid,
|
||||
uint64_t start_time,
|
||||
uint64_t end_time,
|
||||
const uint8_t* meta_data,
|
||||
size_t meta_data_length) {
|
||||
|
||||
// time_at_tail <= start_time <= end_time or else the subtraction
|
||||
// will be invalid
|
||||
if (start_time > end_time || start_time < time_at_tail_) {
|
||||
LOGE("Skipping submission. Submission has time travelled."
|
||||
"Start=%llu End=%llu Tail=%llu. Should be Tail<=Start<=End.",
|
||||
start_time, end_time, time_at_tail_);
|
||||
return;
|
||||
}
|
||||
|
||||
EntryWriter header;
|
||||
header.WriteU8(fid);
|
||||
header.WriteVLV(start_time - time_at_tail_);
|
||||
header.WriteVLV(end_time - start_time);
|
||||
|
||||
const size_t total_packet_size = header.GetSize() + meta_data_length;
|
||||
|
||||
// The max size for a VLV is 8 bytes and the max size for a entry
|
||||
// writer is 32 bytes. Normally the meta data will be packed using
|
||||
// an entry writer so the max packet size will be 64 bytes. Since the
|
||||
// packet size is encoded with a single byte, the packet must first
|
||||
// be checked to ensure it is not too large for the cast.
|
||||
if (total_packet_size <= 255 && RequestSpace(total_packet_size + 1)) {
|
||||
buffer_.AddU8(static_cast<uint8_t>(total_packet_size));
|
||||
buffer_.AddU8s(header.GetData(), header.GetSize());
|
||||
buffer_.AddU8s(meta_data, meta_data_length);
|
||||
|
||||
time_at_tail_ = end_time;
|
||||
}
|
||||
}
|
||||
|
||||
void CallHistory::Read(std::vector<uint8_t>& output) const {
|
||||
output.push_back(kOutputVersionNumber);
|
||||
|
||||
// write the starting time
|
||||
EntryWriter startingTimeWriter;
|
||||
if (-1 == startingTimeWriter.WriteVLV(time_at_head_)) {
|
||||
output.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < startingTimeWriter.GetSize(); i++) {
|
||||
output.push_back(startingTimeWriter.GetData()[i]);
|
||||
}
|
||||
|
||||
// write the whole circular buffer into the output buffer
|
||||
const size_t num_bytes = buffer_.GetUsedSpace();
|
||||
for (size_t i = 0; i < num_bytes; i++) {
|
||||
uint8_t b;
|
||||
if (buffer_.PeekU8(i, &b)) {
|
||||
output.push_back(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CallHistory::RequestSpace(uint8_t num_bytes) {
|
||||
// check if it is possible to make enough room
|
||||
const size_t buffer_size = buffer_.GetFreeSpace() +
|
||||
buffer_.GetUsedSpace();
|
||||
|
||||
if (num_bytes > buffer_size) {
|
||||
LOGE("Requesting more space than possible (requested = %u, max = %zu)",
|
||||
num_bytes, buffer_size);
|
||||
return false;
|
||||
}
|
||||
|
||||
// drop entries until we have enough space
|
||||
while (num_bytes > buffer_.GetFreeSpace() && DropLastEntry());
|
||||
|
||||
return num_bytes <= buffer_.GetFreeSpace();
|
||||
}
|
||||
|
||||
bool CallHistory::ReadNextEntryRealEndTime(uint64_t* output) {
|
||||
if (output == NULL) {
|
||||
LOGE("Cannout output to null pointer");
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t initial_time_start_index = 2;
|
||||
|
||||
uint64_t initial_time;
|
||||
const int initial_time_length =
|
||||
ReadVLV(initial_time_start_index, &initial_time);
|
||||
if (initial_time_length == -1) {
|
||||
LOGE("Failed to read the start time for head entry");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t delta_time;
|
||||
const int delta_time_length = ReadVLV(
|
||||
initial_time_start_index + initial_time_length, &delta_time);
|
||||
|
||||
if (delta_time_length == -1) {
|
||||
LOGE("Failed to read the delta time for head entry");
|
||||
return false;
|
||||
}
|
||||
|
||||
*output = time_at_head_ + initial_time + delta_time;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CallHistory::DropLastEntry() {
|
||||
uint8_t entry_size;
|
||||
uint64_t end_time;
|
||||
|
||||
if (buffer_.PeekU8(0, &entry_size) && ReadNextEntryRealEndTime(&end_time)) {
|
||||
// + 1 because the entry size byte needs to be removed too
|
||||
if (buffer_.Remove(entry_size + 1)) {
|
||||
time_at_head_ = end_time;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int CallHistory::ReadVLV(size_t offset, uint64_t* output) const {
|
||||
uint8_t first_byte;
|
||||
if (buffer_.PeekU8(offset, &first_byte)) {
|
||||
const size_t num_bytes = (first_byte >> 5) + 1;
|
||||
|
||||
uint64_t value = first_byte & 0x1F;
|
||||
for (size_t i = 1; i < num_bytes; i++) {
|
||||
uint8_t next_byte;
|
||||
if (buffer_.PeekU8(offset + i, &next_byte)) {
|
||||
value = value << 8 | next_byte;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
*output = value;
|
||||
return num_bytes;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
} // namespace wvcdm
|
||||
} // namespace oemprofiler
|
||||
|
||||
Reference in New Issue
Block a user