AVI dumper: Performance counters
These are needed for dynamic compression level adjustment (not implemented yet for any codec).
This commit is contained in:
parent
1a8cfbc990
commit
bad7915dfb
5 changed files with 56 additions and 4 deletions
|
@ -85,6 +85,14 @@ public:
|
||||||
* Note: Don't call from outside workthread code.
|
* Note: Don't call from outside workthread code.
|
||||||
*/
|
*/
|
||||||
int operator()(int dummy);
|
int operator()(int dummy);
|
||||||
|
/**
|
||||||
|
* Get wait counters.
|
||||||
|
*
|
||||||
|
* Retrns: Two-element tuple.
|
||||||
|
* - The first element is the amount of microseconds wait_busy() has waited.
|
||||||
|
* - The second element is the amount of microseconds wait_workflag() has waited.
|
||||||
|
*/
|
||||||
|
std::pair<uint64_t, uint64_t> get_wait_count();
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Thread entrypoint.
|
* Thread entrypoint.
|
||||||
|
@ -106,6 +114,8 @@ private:
|
||||||
volatile bool busy;
|
volatile bool busy;
|
||||||
volatile bool exception_caught;
|
volatile bool exception_caught;
|
||||||
volatile bool exception_oom;
|
volatile bool exception_oom;
|
||||||
|
volatile uint64_t waitamt_busy;
|
||||||
|
volatile uint64_t waitamt_work;
|
||||||
std::string exception_text;
|
std::string exception_text;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,13 @@ struct avi_video_codec
|
||||||
* Returns: The packet.
|
* Returns: The packet.
|
||||||
*/
|
*/
|
||||||
virtual avi_packet getpacket() = 0;
|
virtual avi_packet getpacket() = 0;
|
||||||
|
/**
|
||||||
|
* Send performance counters.
|
||||||
|
*
|
||||||
|
* Parameter b: Amount of busywaiting by emulator.
|
||||||
|
* Parameter w: Amount of workwaiting by dumper.
|
||||||
|
*/
|
||||||
|
virtual void send_performance_counters(uint64_t b, uint64_t w);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,16 @@
|
||||||
#include "library/workthread.hpp"
|
#include "library/workthread.hpp"
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
uint64_t ticks()
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
return static_cast<uint64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct worker_thread_reflector
|
struct worker_thread_reflector
|
||||||
{
|
{
|
||||||
|
@ -15,6 +26,8 @@ worker_thread::worker_thread()
|
||||||
reflector = NULL;
|
reflector = NULL;
|
||||||
workflag = 0;
|
workflag = 0;
|
||||||
busy = false;
|
busy = false;
|
||||||
|
waitamt_busy = 0;
|
||||||
|
waitamt_work = 0;
|
||||||
exception_caught = false;
|
exception_caught = false;
|
||||||
exception_oom = false;
|
exception_oom = false;
|
||||||
joined = false;
|
joined = false;
|
||||||
|
@ -58,8 +71,12 @@ void worker_thread::clear_busy()
|
||||||
void worker_thread::wait_busy()
|
void worker_thread::wait_busy()
|
||||||
{
|
{
|
||||||
umutex_class h(mutex);
|
umutex_class h(mutex);
|
||||||
while(busy)
|
if(busy) {
|
||||||
condition.wait(h);
|
uint64_t tmp = ticks();
|
||||||
|
while(busy)
|
||||||
|
condition.wait(h);
|
||||||
|
waitamt_busy += (ticks() - tmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void worker_thread::rethrow()
|
void worker_thread::rethrow()
|
||||||
|
@ -90,11 +107,21 @@ uint32_t worker_thread::clear_workflag(uint32_t flag)
|
||||||
uint32_t worker_thread::wait_workflag()
|
uint32_t worker_thread::wait_workflag()
|
||||||
{
|
{
|
||||||
umutex_class h(mutex);
|
umutex_class h(mutex);
|
||||||
while(!workflag)
|
if(!workflag) {
|
||||||
condition.wait(h);
|
uint64_t tmp = ticks();
|
||||||
|
while(!workflag)
|
||||||
|
condition.wait(h);
|
||||||
|
waitamt_work += (ticks() - tmp);
|
||||||
|
}
|
||||||
return workflag;
|
return workflag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<uint64_t, uint64_t> worker_thread::get_wait_count()
|
||||||
|
{
|
||||||
|
umutex_class h(mutex);
|
||||||
|
return std::make_pair(waitamt_busy, waitamt_work);
|
||||||
|
}
|
||||||
|
|
||||||
int worker_thread::operator()(int dummy)
|
int worker_thread::operator()(int dummy)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -127,6 +127,7 @@ namespace
|
||||||
uint32_t segframes;
|
uint32_t segframes;
|
||||||
uint32_t max_segframes;
|
uint32_t max_segframes;
|
||||||
bool closed;
|
bool closed;
|
||||||
|
avi_video_codec* ivcodec;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define WORKFLAG_QUEUE_FRAME 1
|
#define WORKFLAG_QUEUE_FRAME 1
|
||||||
|
@ -137,6 +138,7 @@ namespace
|
||||||
avi_worker::avi_worker(const struct avi_info& info)
|
avi_worker::avi_worker(const struct avi_info& info)
|
||||||
: aviout(info.prefix, *info.vcodec, *info.acodec, info.sample_rate, info.audio_chans)
|
: aviout(info.prefix, *info.vcodec, *info.acodec, info.sample_rate, info.audio_chans)
|
||||||
{
|
{
|
||||||
|
ivcodec = info.vcodec;
|
||||||
segframes = 0;
|
segframes = 0;
|
||||||
max_segframes = info.max_frames;
|
max_segframes = info.max_frames;
|
||||||
fire();
|
fire();
|
||||||
|
@ -183,6 +185,8 @@ namespace
|
||||||
f.force_break = (segframes == max_segframes && max_segframes > 0);
|
f.force_break = (segframes == max_segframes && max_segframes > 0);
|
||||||
if(f.force_break)
|
if(f.force_break)
|
||||||
segframes = 0;
|
segframes = 0;
|
||||||
|
auto wc = get_wait_count();
|
||||||
|
ivcodec->send_performance_counters(wc.first, wc.second);
|
||||||
memcpy(&f.data[0], frame, 4 * frame_width * frame_height);
|
memcpy(&f.data[0], frame, 4 * frame_width * frame_height);
|
||||||
frame = NULL;
|
frame = NULL;
|
||||||
clear_workflag(WORKFLAG_QUEUE_FRAME);
|
clear_workflag(WORKFLAG_QUEUE_FRAME);
|
||||||
|
|
|
@ -22,6 +22,10 @@ avi_video_codec::format::format(uint32_t _width, uint32_t _height, uint32_t _com
|
||||||
clr_important = 0;
|
clr_important = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void avi_video_codec::send_performance_counters(uint64_t b, uint64_t w)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
avi_audio_codec::format::format(uint16_t tag)
|
avi_audio_codec::format::format(uint16_t tag)
|
||||||
{
|
{
|
||||||
max_bytes_per_sec = 200000;
|
max_bytes_per_sec = 200000;
|
||||||
|
|
Loading…
Add table
Reference in a new issue