Refactor video dump framedrop handling

This commit is contained in:
Ilari Liusvaara 2014-05-31 09:23:47 +03:00
parent 5266f96cfd
commit f036ccd02d
6 changed files with 39 additions and 50 deletions

View file

@ -293,7 +293,6 @@ public:
template<bool X> bool render_video_hud(struct framebuffer::fb<X>& target, struct framebuffer::raw& source,
uint32_t hscl, uint32_t vscl, uint32_t lgap, uint32_t tgap, uint32_t rgap, uint32_t bgap,
std::function<void()> fn);
/**
* Calculate number of sound samples to drop due to dropped frame.
*/
@ -337,9 +336,37 @@ public:
* Dump is being forcibly ended.
*/
virtual void on_end() = 0;
/**
* Render Lua HUD on video. samples_killed is incremented if needed.
*
* Parameter target: The target screen to render on.
* Parameter source: The source screen to read.
* Parameter fps_n: Fps numerator.
* Parameter fps_d: Fps denominator.
* Parameter hscl: The horizontal scale factor.
* Parameter vscl: The vertical scale factor.
* Parameter lgap: Left gap.
* Parameter tgap: Top gap.
* Parameter rgap: Right gap
* Parameter bgap: Bottom gap.
* Parameter fn: Function to call between running lua hooks and actually rendering.
* Returns: True if frame should be dumped, false if not.
*/
template<bool X> bool render_video_hud(struct framebuffer::fb<X>& target, struct framebuffer::raw& source,
uint32_t fps_n, uint32_t fps_d, uint32_t hscl, uint32_t vscl, uint32_t lgap, uint32_t tgap,
uint32_t rgap, uint32_t bgap, std::function<void()> fn)
{
bool r = mdumper->render_video_hud(target, source, hscl, vscl, lgap, tgap, rgap, bgap, fn);
if(!r)
samples_killed += mdumper->killed_audio_length(fps_n, fps_d, akillfrac);
return r;
}
private:
friend class master_dumper;
uint64_t samples_killed;
master_dumper* mdumper;
dumper_factory_base* fbase;
double akillfrac;
};
#endif

View file

@ -161,6 +161,7 @@ dumper_base::dumper_base()
{
mdumper = NULL;
fbase = NULL;
samples_killed = 0;
}
dumper_base::dumper_base(master_dumper& _mdumper, dumper_factory_base& _fbase)
@ -269,6 +270,10 @@ void master_dumper::on_sample(short l, short r)
threads::arlock h(lock);
for(auto i : sdumpers)
try {
if(__builtin_expect(i->samples_killed, 0)) {
i->samples_killed--;
continue;
}
i->on_sample(l, r);
} catch(std::exception& e) {
(*output) << "Error in on_sample: " << e.what() << std::endl;

View file

@ -372,8 +372,6 @@ again:
sbuffer.resize(RESAMPLE_BUFFER * chans);
resampler_w = new resample_worker(worker, ratio, chans);
}
akill = 0;
akillfrac = 0;
mdumper.add_dumper(*this);
} catch(std::bad_alloc& e) {
throw;
@ -411,23 +409,16 @@ again:
rpair(hscl, vscl) = our_rom.rtype->get_scale_factors(_frame.get_width(),
_frame.get_height());
}
if(!mdumper.render_video_hud(dscr, _frame, hscl, vscl, dlb(*CORE().settings),
if(!render_video_hud(dscr, _frame, fps_n, fps_d, hscl, vscl, dlb(*CORE().settings),
dtb(*CORE().settings), drb(*CORE().settings), dbb(*CORE().settings),
[this]() -> void { this->worker->wait_busy(); })) {
akill += mdumper.killed_audio_length(fps_n, fps_d, akillfrac);
[this]() -> void { this->worker->wait_busy(); }))
return;
}
worker->queue_video(dscr.rowptr(0), dscr.get_stride(), dscr.get_width(), dscr.get_height(),
fps_n, fps_d);
have_dumped_frame = true;
}
void on_sample(short l, short r)
{
if(akill) {
akill--;
return;
}
if(resampler_w) {
if(!have_dumped_frame)
return;
@ -484,8 +475,6 @@ again:
std::vector<short> sbuffer;
size_t sbuffer_fill;
uint32_t chans;
uint64_t akill = 0;
double akillfrac = 0;
};
class adv_avi_dumper : public dumper_factory_base

View file

@ -80,8 +80,6 @@ namespace
video_n = 0;
maxtc = 0;
soundrate = mdumper.get_rate();
akill = 0;
akillfrac = 0;
mdumper.add_dumper(*this);
} catch(std::bad_alloc& e) {
throw;
@ -123,10 +121,8 @@ out:
void on_frame(struct framebuffer::raw& _frame, uint32_t fps_n, uint32_t fps_d)
{
if(!mdumper.render_video_hud(dscr, _frame, 1, 1, 0, 0, 0, 0, NULL)) {
akill += mdumper.killed_audio_length(fps_n, fps_d, akillfrac);
if(!render_video_hud(dscr, _frame, fps_n, fps_d, 1, 1, 0, 0, 0, 0, NULL))
return;
}
frame_buffer f;
f.ts = get_next_video_ts(fps_n, fps_d);
//We'll compress the frame here.
@ -139,10 +135,6 @@ out:
void on_sample(short l, short r)
{
if(akill) {
akill--;
return;
}
uint64_t ts = get_next_audio_ts();
if(have_dumped_frame) {
sample_buffer s;
@ -202,8 +194,6 @@ out:
uint64_t video_n;
uint64_t maxtc;
std::pair<uint32_t, uint32_t> soundrate;
uint64_t akill;
double akillfrac;
struct frame_buffer
{
uint64_t ts;

View file

@ -107,8 +107,6 @@ namespace
last_fps_n = 0;
last_fps_d = 0;
segid = hex::from<uint32_t>(get_random_hexstring(8));
akill = 0;
akillfrac = 0;
mdumper.add_dumper(*this);
} catch(std::bad_alloc& e) {
throw;
@ -129,10 +127,8 @@ namespace
}
void on_frame(struct framebuffer::raw& _frame, uint32_t fps_n, uint32_t fps_d)
{
if(!mdumper.render_video_hud(dscr, _frame, 1, 1, 0, 0, 0, 0, NULL)) {
akill += mdumper.killed_audio_length(fps_n, fps_d, akillfrac);
if(!render_video_hud(dscr, _frame, fps_n, fps_d, 1, 1, 0, 0, 0, 0, NULL))
return;
}
size_t w = dscr.get_width();
size_t h = dscr.get_height();
uint32_t stride = dscr.get_stride();
@ -188,10 +184,6 @@ namespace
void on_sample(short l, short r)
{
if(akill) {
akill--;
return;
}
if(have_dumped_frame && audio)
audio->sample(l, r);
}
@ -223,8 +215,6 @@ namespace
uint32_t last_height;
uint32_t last_width;
uint32_t segid;
uint64_t akill;
double akillfrac;
};
class adv_pipedec_dumper : public dumper_factory_base

View file

@ -76,8 +76,6 @@ namespace
have_dumped_frame = false;
swap = _swap;
bits64 = _bits64;
akill = 0;
akillfrac = 0;
mdumper.add_dumper(*this);
} catch(std::bad_alloc& e) {
throw;
@ -110,10 +108,8 @@ namespace
std::vector<uint16_t> tmp;
tmp.resize(8 * s + 8);
uint32_t alignment = (16 - reinterpret_cast<size_t>(&tmp[0])) % 16 / 2;
if(!mdumper.render_video_hud(dscr2, _frame, hscl, vscl, 0, 0, 0, 0, NULL)) {
akill += mdumper.killed_audio_length(fps_n, fps_d, akillfrac);
if(!render_video_hud(dscr2, _frame, fps_n, fps_d, hscl, vscl, 0, 0, 0, 0, NULL))
return;
}
for(size_t i = 0; i < h; i++) {
if(!swap)
framebuffer::copy_swap4(&tmp[alignment], dscr2.rowptr(i), s);
@ -128,10 +124,8 @@ namespace
std::vector<uint8_t> tmp;
tmp.resize(4 * s + 16);
uint32_t alignment = (16 - reinterpret_cast<size_t>(&tmp[0])) % 16;
if(!mdumper.render_video_hud(dscr, _frame, hscl, vscl, 0, 0, 0, 0, NULL)) {
akill += mdumper.killed_audio_length(fps_n, fps_d, akillfrac);
if(!render_video_hud(dscr, _frame, fps_n, fps_d, hscl, vscl, 0, 0, 0, 0, NULL))
return;
}
for(size_t i = 0; i < h; i++) {
if(!swap)
framebuffer::copy_swap4(&tmp[alignment], dscr.rowptr(i), s);
@ -147,10 +141,6 @@ namespace
void on_sample(short l, short r)
{
if(akill) {
akill--;
return;
}
if(have_dumped_frame && audio) {
char buffer[4];
serialization::s16b(buffer + 0, l);
@ -179,8 +169,6 @@ namespace
struct framebuffer::fb<true> dscr2;
bool swap;
bool bits64;
uint64_t akill;
double akillfrac;
master_dumper& mdumper;
};