This source file includes following definitions.
- send_data_to_file
- scrdump_start
- scrdump_frame
- scrdump_finish
- scrdump_task
- scrdump_schedule
- scrdump_menu_schedule
- scrdump_menu_exit
- _run
- _module_unloader
- _module_can_unload
1 #include "camera_info.h"
2 #include "lang.h"
3 #include "conf.h"
4 #include "shooting.h"
5 #include "time.h"
6 #include "clock.h"
7 #include "task.h"
8
9 #include "gui.h"
10 #include "gui_menu.h"
11 #include "gui_lang.h"
12 #include "semaphore.h"
13
14 static int running = 0;
15
16 typedef struct {
17 int handle;
18 int (*send_data)(int handle, const char *buf, int part_size, int total_size, int, int, int);
19 } dummy_ptp_data;
20
21 extern int live_view_get_data(dummy_ptp_data *data, int flags);
22
23 int send_data_to_file(int handle, const char *buf, int part_size, int total_size, __attribute__ ((unused))int u1, __attribute__ ((unused))int u2, __attribute__ ((unused))int u3)
24 {
25
26
27 if(total_size) {
28 write(handle, &total_size, sizeof(total_size));
29 }
30 write(handle, buf, part_size);
31 return 0;
32 }
33 static dummy_ptp_data ptp_data = {
34 -1,
35 send_data_to_file,
36 };
37 static char fn[32];
38
39 static int scrdump_start(void)
40 {
41 running = 1;
42 int fd;
43 static int lvdump_header[] = {
44 0x766c6863,
45 8,
46 1,
47 0,
48 };
49
50 if ( is_video_recording() ) {
51 return -1;
52 }
53
54 mkdir("A/DCIM");
55 mkdir("A/DCIM/100CANON");
56 fd = -1;
57 int cnt = 0;
58 do {
59 sprintf(fn, "A/DCIM/100CANON/CRW_%04d.JPG", cnt++);
60 if (stat(fn,0) != 0) {
61 fd = open(fn, O_WRONLY|O_CREAT, 0777);
62 break;
63 }
64 } while(cnt<9999);
65 if (fd>=0) {
66 ptp_data.handle = fd;
67
68 write(fd, lvdump_header,sizeof(lvdump_header));
69 return 0;
70 }
71 return -1;
72 }
73 static void scrdump_frame(int what)
74 {
75
76 if(ptp_data.handle >= 0) {
77 live_view_get_data(&ptp_data,what);
78 }
79 }
80 static void scrdump_finish(void)
81 {
82 if(ptp_data.handle >= 0) {
83 close(ptp_data.handle);
84 ptp_data.handle = -1;
85 struct utimbuf t;
86 t.actime = t.modtime = time(NULL);
87 utime(fn, &t);
88 }
89 }
90
91
92 enum SCRDUMP_CMD
93 {
94 SCRDUMP_CMD_NONE = 0,
95 SCRDUMP_CMD_SCHEDULE,
96 SCRDUMP_CMD_EXIT,
97 };
98
99 #define CMD_SEM_TIMEOUT 1000
100 static int cmd_sem;
101 static int cmd_next;
102
103 typedef struct {
104 int frame_buffers;
105 int frame_count;
106 int frame_time;
107 int start_delay;
108 } scrdump_settings_t;
109
110 scrdump_settings_t settings_next;
111
112
113 enum SCRDUMP_STATE
114 {
115 SCRDUMP_STATE_IDLE = 0,
116 SCRDUMP_STATE_PENDING,
117 SCRDUMP_STATE_RUN,
118 };
119
120
121 static int scrdump_task_running;
122 void scrdump_task(void)
123 {
124 static scrdump_settings_t settings;
125
126 int state = SCRDUMP_STATE_IDLE;
127 int frames_left = 0;
128
129 unsigned next_action_tick = get_tick_count();
130
131 while(1) {
132 if (!TakeSemaphore(cmd_sem, CMD_SEM_TIMEOUT)) {
133 int cmd = cmd_next;
134 cmd_next = SCRDUMP_CMD_NONE;
135 if(cmd == SCRDUMP_CMD_SCHEDULE) {
136 if(state == SCRDUMP_STATE_RUN) {
137 scrdump_finish();
138 }
139 memcpy(&settings,&settings_next,sizeof(settings));
140 next_action_tick = (unsigned)get_tick_count() + settings.start_delay;
141 frames_left = settings.frame_count;
142 state = SCRDUMP_STATE_PENDING;
143 } else if(cmd == SCRDUMP_CMD_EXIT) {
144 GiveSemaphore(cmd_sem);
145 if(state == SCRDUMP_STATE_RUN) {
146 scrdump_finish();
147 }
148 break;
149 }
150 GiveSemaphore(cmd_sem);
151 }
152 if(state == SCRDUMP_STATE_PENDING) {
153 if(next_action_tick <= (unsigned)get_tick_count()) {
154
155 if(scrdump_start() == 0) {
156 state = SCRDUMP_STATE_RUN;
157 } else {
158 state = SCRDUMP_STATE_IDLE;
159 }
160 }
161 }
162 if(state == SCRDUMP_STATE_RUN) {
163 unsigned t = (unsigned)get_tick_count();
164 if(next_action_tick <= t) {
165 if(frames_left > 0) {
166 scrdump_frame(settings.frame_buffers);
167 frames_left--;
168
169
170 next_action_tick = t + settings.frame_time;
171 }
172 if(frames_left == 0) {
173 scrdump_finish();
174 state = SCRDUMP_STATE_IDLE;
175 }
176 }
177 }
178 if(state == SCRDUMP_STATE_IDLE) {
179 next_action_tick = (unsigned)get_tick_count() + 100;
180 }
181
182 unsigned now = (unsigned)get_tick_count();
183 if(next_action_tick >= now) {
184 unsigned sleep_time = next_action_tick - now;
185
186
187 if(sleep_time > 100) {
188 sleep_time = 100;
189 } else if(sleep_time < 10) {
190 sleep_time = 10;
191 }
192 msleep((long)sleep_time);
193 } else {
194 msleep(10);
195 }
196 }
197 scrdump_task_running = 0;
198 ExitTask();
199 }
200
201
202 static int scrdump_frames = 1;
203 static int scrdump_frame_delay = 10;
204 static int scrdump_buffers = 2;
205 static int scrdump_skip = 0;
206 static int scrdump_delay = 5;
207
208 void scrdump_schedule(void) {
209
210 if (!TakeSemaphore(cmd_sem, CMD_SEM_TIMEOUT)) {
211 cmd_next = SCRDUMP_CMD_SCHEDULE;
212
213 if(scrdump_buffers > 0) {
214 settings_next.frame_buffers = 0x4;
215
216
217 if(!scrdump_skip) {
218 #ifdef THUMB_FW
219 settings_next.frame_buffers |= 0x10;
220 #else
221 settings_next.frame_buffers |= 0x8;
222 #endif
223 }
224 }
225
226
227 if(scrdump_buffers == 0 || scrdump_buffers == 2) {
228 settings_next.frame_buffers |= 1;
229 }
230 settings_next.frame_count = scrdump_frames;
231 settings_next.frame_time = scrdump_frame_delay*10;
232 settings_next.start_delay = scrdump_delay*1000;
233 GiveSemaphore(cmd_sem);
234 }
235 }
236 void scrdump_menu_schedule(void)
237 {
238 scrdump_schedule();
239 gui_set_mode(&altGuiHandler);
240 }
241
242 void scrdump_menu_exit(void)
243 {
244
245 if (!TakeSemaphore(cmd_sem, CMD_SEM_TIMEOUT)) {
246 cmd_next = SCRDUMP_CMD_EXIT;
247 GiveSemaphore(cmd_sem);
248 while(scrdump_task_running) {
249 msleep(10);
250 }
251 gui_set_mode(&altGuiHandler);
252 running = 0;
253 }
254 }
255
256
257 static const char* scrdump_buffer_names[] = { "Viewprt", "Bitmap", "Both"};
258 static CMenuItem scrdump_submenu_items[] = {
259 MENU_ITEM (0x5c,(int)"Schedule dump", MENUITEM_PROC, scrdump_menu_schedule, 0 ),
260 MENU_ITEM (0x2a,(int)"Frames", MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &scrdump_frames, MENU_MINMAX(1, 1000) ),
261 MENU_ITEM (0x2a,(int)"Frame Time (ms*10)", MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &scrdump_frame_delay, MENU_MINMAX(4, 1000)),
262 MENU_ENUM2 (0x5c,(int)"Framebuffers", &scrdump_buffers, scrdump_buffer_names ),
263 #ifdef THUMB_FW
264 MENU_ITEM (0x5c,(int)"Skip Opacity", MENUITEM_BOOL, &scrdump_skip, 0 ),
265 #else
266 MENU_ITEM (0x5c,(int)"Skip Palette", MENUITEM_BOOL, &scrdump_skip, 0 ),
267 #endif
268 MENU_ITEM (0x2a,(int)"Dump Start Delay (s)", MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &scrdump_delay, MENU_MINMAX(0, 60)),
269 MENU_ITEM (0x5c,(int)"Exit module", MENUITEM_PROC, scrdump_menu_exit, 0 ),
270 MENU_ITEM (0x51,LANG_MENU_BACK, MENUITEM_UP, 0, 0 ),
271 {0}
272 };
273
274 static CMenu scrdump_submenu = {0x2a,(int)"Screen Dump Settings", scrdump_submenu_items };
275
276 int _run()
277 {
278 running = 1;
279 if(!cmd_sem) {
280 cmd_sem = CreateBinarySemaphore("ScrDumpCmd", 1);
281 }
282 if(!scrdump_task_running) {
283
284 CreateTask("ScrDump",0x1A,0x800,scrdump_task);
285 scrdump_task_running = 1;
286 }
287
288 gui_activate_sub_menu(&scrdump_submenu);
289 return 0;
290 }
291
292 #include "simple_module.h"
293
294
295
296
297
298
299
300
301
302
303
304 int _module_unloader()
305 {
306 if(cmd_sem) {
307 DeleteSemaphore(cmd_sem);
308 }
309 return 0;
310 }
311
312 int _module_can_unload()
313 {
314 return (running == 0);
315 }
316
317
318
319 libsimple_sym _libscrdump =
320 {
321 {
322 0, _module_unloader, _module_can_unload, 0, _run
323 },
324 };
325
326 ModuleInfo _module_info = {
327 MODULEINFO_V1_MAGICNUM,
328 sizeof(ModuleInfo),
329 SIMPLE_MODULE_VERSION,
330
331 ANY_CHDK_BRANCH, 0, OPT_ARCHITECTURE,
332 ANY_PLATFORM_ALLOWED,
333
334 (int)"Screen Record",
335 MTYPE_TOOL|MTYPE_SUBMENU_TOOL,
336
337 &_libscrdump.base,
338
339 CONF_VERSION,
340 CAM_SCREEN_VERSION,
341 ANY_VERSION,
342 CAM_INFO_VERSION,
343 0,
344 };
345
346