1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
/*############################################################################
# Copyright (C) 2005 Intel Corporation
#
# SPDX-License-Identifier: MIT
############################################################################*/
#ifndef __SMT_TRACER_H__
#define __SMT_TRACER_H__
#include <algorithm>
#include <chrono>
#include <condition_variable>
#include <fstream>
#include <map>
#include <mutex>
#include <string>
#include <vector>
#include "vpl/mfxdefs.h"
namespace TranscodingSample {
class SMTTracer {
public:
enum class PipelineType { unknown, _1x1, _1xN, _NxN };
enum class ThreadType { DEC, CSVPP, VPP, ENC };
enum class EventName { UNDEF, BUSY, SYNC, READ_YUV, READ_BS, WRITE_BS, SURF_WAIT };
enum class EventType { DurationStart, DurationEnd, FlowStart, FlowEnd, Counter };
enum class LatencyType { DEFAULT, E2E, ENC };
SMTTracer();
~SMTTracer();
void Init(const PipelineType type,
const mfxU32 numOfChannels,
const LatencyType latency,
const mfxU32 TraceBufferSize);
void BeginEvent(const ThreadType thType,
const mfxU32 thID,
const EventName name,
const void* inID,
const void* outID);
void EndEvent(const ThreadType thType,
const mfxU32 thID,
const EventName name,
const void* inID,
const void* outID);
void AddCounterEvent(const ThreadType thType,
const mfxU32 thID,
const EventName name,
const mfxU64 counter);
void BeforeDecodeStart();
void AfterDecodeStart();
void BeforeEncodeStart();
void AfterDecodeSync();
void AfterEncodeSync();
private:
class Event {
public:
EventType EvType; //duration, flow, counter
ThreadType ThType; //dec, vpp, enc, csvpp
mfxU32 ThID; //channel or pool number in 1toN pipeline
EventName Name; //optional, if not specifyed thread name will be used
mfxU32 EvID; //unique event ID
mfxU64 InID; //unique dependency ID, e.g. surface pointer
mfxU64 OutID;
mfxU64 TS; //time stamp
Event()
: EvType(EventType::DurationStart),
ThType(ThreadType::DEC),
ThID(0),
Name(EventName::UNDEF),
EvID(0),
InID(0),
OutID(0),
TS(0) {}
};
using EventIt = std::vector<Event>::iterator;
class TimeInterval {
public:
TimeInterval(mfxU64 ts, mfxU64 duration);
mfxU64 TS; //beginning of time interval, wall clock
mfxU64 Duration;
};
//runtime functions
void AddEvent(const EventType evType,
const ThreadType thType,
const mfxU32 thID,
const EventName name,
const void* inID,
const void* outID);
mfxU64 GetCurrentTS();
//log generation functions
void AdjustOverlappingEvents();
void SaveTrace(mfxU32 FileID);
void AddFlowEvents();
void AddFlowEvent(const Event a, const Event b);
void ComputeE2ELatency();
void ComputeEncLatency();
void SaveLatency(LatencyType type,
mfxU32 FileID,
std::map<mfxU32, std::vector<TimeInterval>>& latency);
EventIt FindBeginningOfDependencyChain(EventIt it);
EventIt FindBeginningOfDurationEvent(EventIt it);
EventIt FindEndOfPreviosDurationEvent(EventIt it);
EventIt FindEventInThread(EventIt first, EventType type);
void WriteEvent(std::ofstream& trace_file, const Event ev);
void WriteDurationEvent(std::ofstream& trace_file, const Event ev);
void WriteFlowEvent(std::ofstream& trace_file, const Event ev);
void WriteCounterEvent(std::ofstream& trace_file, const Event ev);
void WriteEventPID(std::ofstream& trace_file);
void WriteEventTID(std::ofstream& trace_file, const Event ev);
void WriteEventTS(std::ofstream& trace_file, const Event ev);
void WriteEventPhase(std::ofstream& trace_file, const Event ev);
void WriteEventName(std::ofstream& trace_file, const Event ev);
void WriteBindingPoint(std::ofstream& trace_file, const Event ev);
void WriteEventInOutIDs(std::ofstream& trace_file, const Event ev);
void WriteEventCounter(std::ofstream& trace_file, const Event ev);
void WriteEventCategory(std::ofstream& trace_file);
void WriteEvID(std::ofstream& trace_file, const Event ev);
void WriteComma(std::ofstream& trace_file);
mfxU32 TraceBufferSizeInMBytes = 7;
const mfxU32 MaxTraceBufferSizeInMBytes = 128;
bool Enabled = false;
PipelineType TypeOfPipeline = PipelineType::unknown;
mfxU32 EvID = 0;
std::vector<Event> Log;
std::vector<Event> AddonLog;
std::map<mfxU32, std::vector<TimeInterval>> E2ELatency;
std::map<mfxU32, std::vector<TimeInterval>> EncLatency;
mfxU32 NumOfErrors = 0;
mfxU64 TimeBase = 0; //moment of time when tracer has been created
std::mutex TracerMutex;
LatencyType TypeOfLatency = LatencyType::DEFAULT;
int NumOfChannels = 0; //this is "N" in 1toN
int NumOfActiveDecoders = 0;
int NumOfActiveEncoders = 0; //number of encoders that are still running
std::condition_variable DecSync{}; //wake up decoder
std::condition_variable EncSync{}; //wake up encoders
const mfxU32 MaxFrameLatencyInMilliseconds = 200;
};
} // namespace TranscodingSample
#endif
|