1 #include "videodumper.hpp"
2 #include "settings.hpp"
3 #include "videodumper2.hpp"
10 #include "fieldsplit.hpp"
11 #include "command.hpp"
13 avidumper
* vid_dumper
= NULL
;
15 void update_movie_state();
20 boolean_setting
dump_large("large-video", false);
22 class dump_video_command
: public command
25 dump_video_command() throw(std::bad_alloc
) : command("dump-video") {}
26 void invoke(const std::string
& args
, window
* win
) throw(std::bad_alloc
, std::runtime_error
)
28 tokensplitter
t(args
);
29 std::string level
= t
;
30 std::string prefix
= t
.tail();
32 throw std::runtime_error("Expected prefix");
34 throw std::runtime_error("Video dumping already in progress");
37 level2
= parse_value
<unsigned long>(level
);
39 throw std::runtime_error("Level must be 0-18");
40 } catch(std::bad_alloc
& e
) {
42 } catch(std::runtime_error
& e
) {
43 throw std::runtime_error("Bad video compression level '" + level
+ "': " + e
.what());
45 struct avi_info parameters
;
46 parameters
.compression_level
= (level2
> 9) ? (level2
- 9) : level2
;
47 parameters
.audio_drop_counter_inc
= 81;
48 parameters
.audio_drop_counter_max
= 64081;
49 parameters
.audio_sampling_rate
= 32000;
50 parameters
.audio_native_sampling_rate
= 32040.5;
51 parameters
.keyframe_interval
= (level2
> 9) ? 300 : 1;
53 vid_dumper
= new avidumper(prefix
, parameters
);
54 } catch(std::bad_alloc
& e
) {
56 } catch(std::exception
& e
) {
58 x
<< "Error starting dump: " << e
.what();
59 throw std::runtime_error(x
.str());
61 out(win
) << "Dumping to " << prefix
<< " at level " << level2
<< std::endl
;
64 std::string
get_short_help() throw(std::bad_alloc
) { return "Start video capture"; }
65 std::string
get_long_help() throw(std::bad_alloc
)
67 return "Syntax: dump-video <level> <prefix>\n"
68 "Start video capture to <prefix> using compression\n"
69 "level <level> (0-18).\n";
73 class end_video_command
: public command
76 end_video_command() throw(std::bad_alloc
) : command("end-video") {}
77 void invoke(const std::string
& args
, window
* win
) throw(std::bad_alloc
, std::runtime_error
)
80 throw std::runtime_error("This command does not take parameters");
82 throw std::runtime_error("No video dump in progress");
85 out(win
) << "Dump finished" << std::endl
;
86 } catch(std::bad_alloc
& e
) {
88 } catch(std::exception
& e
) {
89 out(win
) << "Error ending dump: " << e
.what() << std::endl
;
95 std::string
get_short_help() throw(std::bad_alloc
) { return "End video capture"; }
96 std::string
get_long_help() throw(std::bad_alloc
)
98 return "Syntax: end-video\n"
99 "End a video capture.\n";
105 void end_vid_dump() throw(std::bad_alloc
, std::runtime_error
)
109 vid_dumper
->on_end();
110 } catch(std::bad_alloc
& e
) {
112 } catch(std::exception
& e
) {
113 std::cerr
<< "Error ending dump: " << e
.what() << std::endl
;
117 void dump_frame(lcscreen
& ls
, render_queue
* rq
, uint32_t left
, uint32_t right
, uint32_t top
, uint32_t bottom
,
118 bool region
, window
* win
) throw(std::bad_alloc
, std::runtime_error
)
122 vid_dumper
->wait_idle();
125 if(dump_large
&& ls
.width
< 400)
127 if(dump_large
&& ls
.height
< 400)
129 uint32_t _magic
= 403703808;
130 uint8_t* magic
= reinterpret_cast<uint8_t*>(&_magic
);
131 dscr
.reallocate(left
+ hscl
* ls
.width
+ right
, top
+ vscl
* ls
.height
+ bottom
, left
, top
,
133 dscr
.set_palette(magic
[2], magic
[1], magic
[0]);
134 dscr
.copy_from(ls
, hscl
, vscl
);
140 uint32_t fps_n
= 10738636;
141 uint32_t fps_d
= 178683;
146 vid_dumper
->on_frame(dscr
.memory
, dscr
.width
, dscr
.height
, fps_n
, fps_d
);
147 } catch(std::bad_alloc
& e
) {
149 } catch(std::exception
& e
) {
150 out(win
) << "Error sending video frame: " << e
.what() << std::endl
;
156 void dump_audio_sample(int16_t l_sample
, int16_t r_sample
, window
* win
) throw(std::bad_alloc
, std::runtime_error
)
160 vid_dumper
->on_sample(l_sample
, r_sample
);
161 } catch(std::bad_alloc
& e
) {
163 } catch(std::exception
& e
) {
164 out(win
) << "Error sending audio sample: " << e
.what() << std::endl
;
168 bool dump_in_progress() throw()
170 return (vid_dumper
!= NULL
);
173 void video_fill_shifts(uint32_t& r
, uint32_t& g
, uint32_t& b
)
175 r
= dscr
.active_rshift
;
176 g
= dscr
.active_gshift
;
177 b
= dscr
.active_bshift
;