blob: 2495e8c4b320e57e1b0ec12c922ca41efeee5388 [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* 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 ANDROID_MEDIA_NBLOG_READER_H
#define ANDROID_MEDIA_NBLOG_READER_H
#include <memory>
#include <stddef.h>
#include <string>
#include <unordered_set>
#include <media/nblog/Entry.h>
#include <media/nblog/Events.h>
#include <utils/RefBase.h>
class audio_utils_fifo;
class audio_utils_fifo_reader;
namespace android {
class IMemory;
class String8;
namespace NBLog {
struct Shared;
// NBLog Reader API
class Snapshot; // Forward declaration needed for Reader::getSnapshot()
class Reader : public RefBase {
public:
// Input parameter 'size' is the desired size of the timeline in byte units.
// The size of the shared memory must be at least Timeline::sharedSize(size).
Reader(const void *shared, size_t size, const std::string &name);
Reader(const sp<IMemory>& iMemory, size_t size, const std::string &name);
~Reader() override;
// get snapshot of readers fifo buffer, effectively consuming the buffer
std::unique_ptr<Snapshot> getSnapshot(bool flush = true);
bool isIMemory(const sp<IMemory>& iMemory) const;
const std::string &name() const { return mName; }
private:
// Amount of tries for reader to catch up with writer in getSnapshot().
static constexpr int kMaxObtainTries = 3;
// invalidBeginTypes and invalidEndTypes are used to align the Snapshot::begin() and
// Snapshot::end() EntryIterators to valid entries.
static const std::unordered_set<Event> invalidBeginTypes;
static const std::unordered_set<Event> invalidEndTypes;
// declared as const because audio_utils_fifo() constructor
sp<IMemory> mIMemory; // ref-counted version, assigned only in constructor
const std::string mName; // name of reader (actually name of writer)
/*const*/ Shared* const mShared; // raw pointer to shared memory, actually const but not
audio_utils_fifo * const mFifo; // FIFO itself,
// non-NULL unless constructor fails
audio_utils_fifo_reader * const mFifoReader; // used to read from FIFO,
// non-NULL unless constructor fails
// Searches for the last valid entry in the range [front, back)
// back has to be entry-aligned. Returns nullptr if none enconuntered.
static const uint8_t *findLastValidEntry(const uint8_t *front, const uint8_t *back,
const std::unordered_set<Event> &invalidTypes);
};
// A snapshot of a readers buffer
// This is raw data. No analysis has been done on it
class Snapshot {
public:
~Snapshot() { delete[] mData; }
// amount of data lost (given by audio_utils_fifo_reader)
size_t lost() const { return mLost; }
// iterator to beginning of readable segment of snapshot
// data between begin and end has valid entries
EntryIterator begin() const { return mBegin; }
// iterator to end of readable segment of snapshot
EntryIterator end() const { return mEnd; }
private:
Snapshot() = default;
explicit Snapshot(size_t bufferSize) : mData(new uint8_t[bufferSize]) {}
friend std::unique_ptr<Snapshot> Reader::getSnapshot(bool flush);
uint8_t * const mData = nullptr;
size_t mLost = 0;
EntryIterator mBegin;
EntryIterator mEnd;
};
// TODO move this to MediaLogService?
class DumpReader : public NBLog::Reader {
public:
DumpReader(const void *shared, size_t size, const std::string &name)
: Reader(shared, size, name) {}
DumpReader(const sp<IMemory>& iMemory, size_t size, const std::string &name)
: Reader(iMemory, size, name) {}
void dump(int fd, size_t indent = 0);
private:
void handleAuthor(const AbstractEntry& fmtEntry __unused, String8* body __unused) {}
EntryIterator handleFormat(const FormatEntry &fmtEntry, String8 *timestamp, String8 *body);
static void appendInt(String8 *body, const void *data);
static void appendFloat(String8 *body, const void *data);
static void appendPID(String8 *body, const void *data, size_t length);
static void appendTimestamp(String8 *body, const void *data);
// The bufferDump functions are used for debugging only.
static String8 bufferDump(const uint8_t *buffer, size_t size);
static String8 bufferDump(const EntryIterator &it);
};
} // namespace NBLog
} // namespace android
#endif // ANDROID_MEDIA_NBLOG_READER_H