2011-11-05 00:37:32 +02:00
|
|
|
#include "sdmp.hpp"
|
2012-01-11 01:21:13 +02:00
|
|
|
#include "core/advdumper.hpp"
|
2011-11-06 14:41:41 +02:00
|
|
|
#include "core/command.hpp"
|
2011-11-08 21:22:30 +02:00
|
|
|
#include "core/dispatch.hpp"
|
2011-11-06 14:41:41 +02:00
|
|
|
#include "core/lua.hpp"
|
|
|
|
#include "core/misc.hpp"
|
|
|
|
#include "core/settings.hpp"
|
|
|
|
|
2011-11-05 00:37:32 +02:00
|
|
|
#include <iomanip>
|
|
|
|
#include <cassert>
|
|
|
|
#include <cstring>
|
|
|
|
#include <sstream>
|
|
|
|
#include <zlib.h>
|
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
2011-11-08 21:22:30 +02:00
|
|
|
class sdmp_avsnoop : public information_dispatch
|
2011-11-05 00:37:32 +02:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
sdmp_avsnoop(const std::string& prefix, bool ssflag) throw(std::bad_alloc)
|
2011-11-08 21:22:30 +02:00
|
|
|
: information_dispatch("dump-sdmp")
|
2011-11-05 00:37:32 +02:00
|
|
|
{
|
2012-01-06 17:28:01 +02:00
|
|
|
enable_send_sound();
|
2011-11-05 00:37:32 +02:00
|
|
|
dumper = new sdump_dumper(prefix, ssflag);
|
|
|
|
}
|
|
|
|
|
|
|
|
~sdmp_avsnoop() throw()
|
|
|
|
{
|
|
|
|
delete dumper;
|
|
|
|
}
|
|
|
|
|
2011-11-08 21:22:30 +02:00
|
|
|
void on_raw_frame(const uint32_t* raw, bool hires, bool interlaced, bool overscan, unsigned region)
|
2011-11-05 00:37:32 +02:00
|
|
|
{
|
|
|
|
unsigned flags = 0;
|
|
|
|
dumper->frame(raw, (hires ? SDUMP_FLAG_HIRES : 0) | (interlaced ? SDUMP_FLAG_INTERLACED : 0) |
|
2011-11-08 21:22:30 +02:00
|
|
|
(overscan ? SDUMP_FLAG_OVERSCAN : 0) | (region == VIDEO_REGION_PAL ? SDUMP_FLAG_PAL :
|
2011-11-05 00:37:32 +02:00
|
|
|
0));
|
|
|
|
}
|
|
|
|
|
2011-11-08 21:22:30 +02:00
|
|
|
void on_sample(short l, short r)
|
2011-11-05 00:37:32 +02:00
|
|
|
{
|
|
|
|
dumper->sample(l, r);
|
|
|
|
}
|
|
|
|
|
2011-11-08 21:22:30 +02:00
|
|
|
void on_dump_end()
|
2011-11-05 00:37:32 +02:00
|
|
|
{
|
|
|
|
dumper->end();
|
|
|
|
}
|
2011-11-08 21:22:30 +02:00
|
|
|
|
|
|
|
bool get_dumper_flag() throw()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
2011-11-05 00:37:32 +02:00
|
|
|
private:
|
|
|
|
sdump_dumper* dumper;
|
|
|
|
};
|
|
|
|
|
|
|
|
sdmp_avsnoop* vid_dumper;
|
|
|
|
|
2012-01-11 01:21:13 +02:00
|
|
|
void startdump(bool ss, const std::string& prefix)
|
|
|
|
{
|
|
|
|
if(prefix == "") {
|
|
|
|
if(ss)
|
|
|
|
throw std::runtime_error("Expected filename");
|
|
|
|
else
|
2011-11-05 00:37:32 +02:00
|
|
|
throw std::runtime_error("Expected prefix");
|
2012-01-11 01:21:13 +02:00
|
|
|
}
|
|
|
|
if(vid_dumper)
|
|
|
|
throw std::runtime_error("SDMP Dump already in progress");
|
|
|
|
try {
|
|
|
|
vid_dumper = new sdmp_avsnoop(prefix, ss);
|
|
|
|
} catch(std::bad_alloc& e) {
|
|
|
|
throw;
|
|
|
|
} catch(std::exception& e) {
|
|
|
|
std::ostringstream x;
|
|
|
|
x << "Error starting SDMP dump: " << e.what();
|
|
|
|
throw std::runtime_error(x.str());
|
|
|
|
}
|
|
|
|
if(ss)
|
|
|
|
messages << "Dumping SDMP (SS) to " << prefix << std::endl;
|
|
|
|
else
|
2011-11-05 00:37:32 +02:00
|
|
|
messages << "Dumping SDMP to " << prefix << std::endl;
|
2012-01-11 01:21:13 +02:00
|
|
|
information_dispatch::do_dumper_update();
|
|
|
|
}
|
|
|
|
|
|
|
|
void enddump()
|
|
|
|
{
|
|
|
|
if(!vid_dumper)
|
|
|
|
throw std::runtime_error("No SDMP video dump in progress");
|
|
|
|
try {
|
|
|
|
vid_dumper->on_dump_end();
|
|
|
|
messages << "SDMP Dump finished" << std::endl;
|
|
|
|
} catch(std::bad_alloc& e) {
|
|
|
|
throw;
|
|
|
|
} catch(std::exception& e) {
|
|
|
|
messages << "Error ending SDMP dump: " << e.what() << std::endl;
|
|
|
|
}
|
|
|
|
delete vid_dumper;
|
|
|
|
vid_dumper = NULL;
|
|
|
|
information_dispatch::do_dumper_update();
|
|
|
|
}
|
|
|
|
|
|
|
|
function_ptr_command<const std::string&> sdmp_dump("dump-sdmp", "Start sdmp capture",
|
|
|
|
"Syntax: dump-sdmp <prefix>\nStart SDMP capture to <prefix>\n",
|
|
|
|
[](const std::string& prefix) throw(std::bad_alloc, std::runtime_error) {
|
|
|
|
startdump(false, prefix);
|
2011-11-05 00:37:32 +02:00
|
|
|
});
|
|
|
|
|
2012-01-11 01:21:13 +02:00
|
|
|
function_ptr_command<const std::string&> sdmp_dumpss("dump-sdmpss", "Start SS sdmp capture",
|
2011-11-05 00:37:32 +02:00
|
|
|
"Syntax: dump-sdmpss <file>\nStart SS SDMP capture to <file>\n",
|
|
|
|
[](const std::string& prefix) throw(std::bad_alloc, std::runtime_error) {
|
2012-01-11 01:21:13 +02:00
|
|
|
startdump(true, prefix);
|
2011-11-05 00:37:32 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
function_ptr_command<> end_avi("end-sdmp", "End SDMP capture",
|
|
|
|
"Syntax: end-sdmp\nEnd a SDMP capture.\n",
|
|
|
|
[]() throw(std::bad_alloc, std::runtime_error) {
|
2012-01-11 01:21:13 +02:00
|
|
|
enddump();
|
2011-11-05 00:37:32 +02:00
|
|
|
});
|
2012-01-11 01:21:13 +02:00
|
|
|
|
|
|
|
class adv_sdmp_dumper : public adv_dumper
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
adv_sdmp_dumper() : adv_dumper("INTERNAL-SDMP") { information_dispatch::do_dumper_update(); }
|
|
|
|
~adv_sdmp_dumper() throw();
|
|
|
|
std::set<std::string> list_submodes() throw(std::bad_alloc)
|
|
|
|
{
|
|
|
|
std::set<std::string> x;
|
|
|
|
x.insert("ss");
|
|
|
|
x.insert("ms");
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool wants_prefix(const std::string& mode) throw()
|
|
|
|
{
|
|
|
|
return (mode != "ss");
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string name() throw(std::bad_alloc)
|
|
|
|
{
|
|
|
|
return "SDMP";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string modename(const std::string& mode) throw(std::bad_alloc)
|
|
|
|
{
|
|
|
|
return (mode == "ss" ? "Single-Segment" : "Multi-Segment");
|
|
|
|
}
|
|
|
|
|
|
|
|
bool busy()
|
|
|
|
{
|
|
|
|
return (vid_dumper != NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
void start(const std::string& mode, const std::string& targetname) throw(std::bad_alloc,
|
|
|
|
std::runtime_error)
|
|
|
|
{
|
|
|
|
startdump((mode == "ss"), targetname);
|
|
|
|
}
|
|
|
|
|
|
|
|
void end() throw()
|
|
|
|
{
|
|
|
|
enddump();
|
|
|
|
}
|
|
|
|
} adv;
|
|
|
|
|
|
|
|
adv_sdmp_dumper::~adv_sdmp_dumper() throw()
|
|
|
|
{
|
|
|
|
}
|
2011-11-05 00:37:32 +02:00
|
|
|
}
|