11#include <promeki/config.h>
12#if PROMEKI_ENABLE_PROAV
24PROMEKI_NAMESPACE_BEGIN
89class DebugMediaFile :
public ObjectBase {
90 PROMEKI_OBJECT(DebugMediaFile, ObjectBase)
93 using UPtr = UniquePtr<DebugMediaFile>;
111 Metadata sessionInfo;
115 struct FrameIndexEntry {
116 int64_t fileOffset = 0;
117 FrameNumber frameNumber;
118 int64_t presentationUs =
123 static constexpr char kMagic[8] = {
'P',
'M',
'D',
'F',
'\x1A',
'\x0A',
'\x00',
'\x00'};
126 static constexpr uint32_t kFormatVersion = 1;
129 static constexpr uint32_t kFileFlagHasFooter = 0x00000001;
132 explicit DebugMediaFile(ObjectBase *parent =
nullptr);
135 ~DebugMediaFile()
override;
151 Error open(
const String &filename, Mode mode,
const OpenOptions &opts = {});
167 bool isOpen()
const {
return _mode != NotOpen; }
170 Mode mode()
const {
return _mode; }
173 const String &filename()
const {
return _filename; }
190 Error writeFrame(
const Frame &frame);
193 FrameCount framesWritten()
const {
return _framesWritten; }
207 Error readFrame(Frame &out);
222 Error readFrameAt(
const FrameNumber &frameNumber, Frame &out);
233 Error seek(
const FrameNumber &frameNumber);
236 const Metadata &sessionInfo()
const {
return _sessionInfo; }
239 FrameCount frameCount()
const;
242 bool hasFooter()
const {
return (_fileFlags & kFileFlagHasFooter) != 0; }
248 const List<FrameIndexEntry> &index()
const;
252 Mode _mode = NotOpen;
253 File *_file =
nullptr;
254 uint32_t _fileFlags = 0;
255 uint32_t _fileVersion = 0;
256 int64_t _firstFramePos = 0;
257 FrameCount _framesWritten{0};
258 mutable FrameNumber _readCursor{0};
259 mutable bool _indexBuilt =
false;
260 mutable List<FrameIndexEntry> _index;
261 Metadata _sessionInfo;
263 Error writeSignature(uint32_t flags);
264 Error writeSessionChunk(
const Metadata &sessionInfo);
265 Error readSignature();
266 Error readSessionChunk();
267 Error appendFooter();
268 Error buildIndex()
const;