1 // ldvgrab.c
2 // LiVES
3 // (c) G. Finch 2006 - 2016 <salsaman@gmail.com>
4 // released under the GNU GPL 3 or later
5 // see file ../COPYING for licensing details
6 
7 // portions of this file (c) Dan Dennedy (dan@dennedy.org)
8 
9 #include <sys/poll.h>
10 #include <netinet/in.h>
11 #include <sys/resource.h>
12 
13 #define RX_CHANNEL 63
14 #define RAW_BUF_SIZE 4096
15 
16 unsigned char g_rx_packet[RAW_BUF_SIZE]; /* the received packet data */
17 int g_rx_length; /* the size of a received packet */
18 int g_alldone = 0; /* flag to indicate when to quit */
19 int g_rx_channel = RX_CHANNEL;
20 
21 //////////////////////////////////////////////////////////////////////////
22 
23 #include "main.h"
24 #include "ldvinterface.h"
25 #include "ldvcallbacks.h"
26 
raw_iso_handler(raw1394handle_t handle,int channel,size_t length,quadlet_t * data)27 int raw_iso_handler(raw1394handle_t handle, int channel, size_t length, quadlet_t *data) {
28   if (length < RAW_BUF_SIZE && channel == g_rx_channel) {
29     g_rx_length = length;
30     lives_memcpy(g_rx_packet, data, length);
31   }
32   return 0;
33 }
34 
35 /* libraw1394 executes this when there is a bus reset. We'll just keep it
36    simple and quit */
reset_handler(raw1394handle_t handle,unsigned int generation)37 int reset_handler(raw1394handle_t handle, unsigned int generation) {
38   raw1394_update_generation(handle, generation);
39   on_camquit_clicked(NULL, dvgrabw->cam);
40   return 0;
41 }
42 
43 
open_raw1394(void)44 raw1394handle_t open_raw1394(void) {
45   int numcards;
46   struct raw1394_portinfo pinf[16];
47   raw1394handle_t handle;
48   struct pollfd raw1394_poll;
49 
50   if (!(handle = raw1394_new_handle())) {
51     d_print(_("raw1394 - couldn't get handle"));
52     do_error_dialog(_("\nThe ieee1394 driver is not loaded or /dev/raw1394 does not exist.\n"));
53     return NULL;
54   }
55 
56   if ((numcards = raw1394_get_port_info(handle, pinf, 16)) < 0) {
57     do_error_dialog(_("\nraw1394 - couldn't get card info.\n"));
58     return NULL;
59   }
60 
61   /* port 0 is the first host adapter card */
62   if (raw1394_set_port(handle, 0) < 0) {
63     do_error_dialog(_("\nraw1394 - couldn't set port.\n"));
64     return NULL;
65   }
66 
67   /* tell libraw1394 the names of our callback functions */
68   //raw1394_set_iso_handler(handle, g_rx_channel, raw_iso_handler);
69   raw1394_set_bus_reset_handler(handle, reset_handler);
70 
71   /* poll for leftover events */
72   raw1394_poll.fd = raw1394_get_fd(handle);
73   raw1394_poll.events = POLLIN;
74 
75   while (1) {
76     if (poll(&raw1394_poll, 1, 10) < 1) break;
77     raw1394_loop_iterate(handle);
78   }
79 
80   /* Starting iso receive */
81   /*  if (raw1394_start_iso_rcv(handle, g_rx_channel) < 0) {
82     do_error_dialog(_("\nraw1394 - couldn't start iso receive.\n"));
83     return NULL;
84     }*/
85   return handle;
86 }
87 
88 
close_raw1394(raw1394handle_t handle)89 void close_raw1394(raw1394handle_t handle) {
90   //raw1394_stop_iso_rcv(handle, g_rx_channel);
91   raw1394_destroy_handle(handle);
92 }
93 
94 
camdest(s_cam * cam)95 void camdest(s_cam *cam) {
96   raw1394_destroy_handle(cam->handle);
97   lives_free(cam);
98 }
99 
100 
camready(void)101 s_cam *camready(void) {
102   rom1394_directory rom_dir;
103 
104   struct raw1394_portinfo pinf[16];
105 
106   s_cam *cam = (s_cam *)lives_malloc(sizeof(s_cam));
107 
108   char *msg;
109 
110   int n_ports;
111 
112   register int i, j;
113 
114   cam->device = -1;
115 
116 #ifdef RAW1394_V_0_8
117   cam->handle = raw1394_get_handle();
118 #else
119   cam->handle = raw1394_new_handle();
120 #endif
121 
122   if (!cam->handle) {
123     if (!errno) {
124       do_error_dialog(_("\nraw1394 device not compatible!\n"));
125     } else {
126       d_print(_("Couldn't get 1394 handle"));
127       do_error_dialog(_("\nIs ieee1394, driver, and raw1394 loaded?\n"));
128     }
129     return NULL;
130   }
131 
132   if ((n_ports = raw1394_get_port_info(cam->handle, pinf, 16)) < 0) {
133     msg = lives_strdup_printf(_("raw1394 - failed to get port info: %s.\n"), lives_strerror(errno));
134     d_print(msg);
135     lives_free(msg);
136     raw1394_destroy_handle(cam->handle);
137     return NULL;
138   }
139 
140 
141   for (j = 0; j < n_ports && cam->device == -1; j++) {
142     if (raw1394_set_port(cam->handle, j) < 0) {
143       msg = lives_strdup_printf(_("\nraw1394 - couldn't set port %d !\n"), j);
144       d_print(msg);
145       lives_free(msg);
146       continue;
147     }
148 
149     for (i = 0; i < raw1394_get_nodecount(cam->handle); ++i) {
150       if (rom1394_get_directory(cam->handle, i, &rom_dir) < 0) {
151         msg = lives_strdup_printf(_("error reading config rom directory for node %d\n"), i);
152         d_print(msg);
153         lives_free(msg);
154         continue;
155       }
156 
157       if ((rom1394_get_node_type(&rom_dir) == ROM1394_NODE_TYPE_AVC) &&
158           avc1394_check_subunit_type(cam->handle, i, AVC1394_SUBUNIT_TYPE_VCR)) {
159         cam->device = i;
160         break;
161       }
162     }
163   }
164 
165   if (0 && cam->device == -1) {
166     do_error_dialog(
167       _("\nLiVES could not find any firewire camera.\nPlease make sure your camera is switched on,\n"
168         "and check that you have read/write permissions for the camera device\n(generally /dev/raw1394*).\n"));
169     raw1394_destroy_handle(cam->handle);
170     return NULL;
171   }
172 
173   return cam;
174 }
175 
176 
177 //////////////////////////////////////////////////////////////////////////////////////////////
178 
camplay(s_cam * cam)179 void camplay(s_cam *cam) {
180   avc1394_vcr_play(cam->handle, cam->device);
181 }
182 
183 
camstop(s_cam * cam)184 void camstop(s_cam *cam) {
185   g_alldone = 1;
186   avc1394_vcr_stop(cam->handle, cam->device);
187 }
188 
189 
camrew(s_cam * cam)190 void camrew(s_cam *cam) {
191   avc1394_vcr_rewind(cam->handle, cam->device);
192 }
193 
194 
camff(s_cam * cam)195 void camff(s_cam *cam) {
196   avc1394_vcr_forward(cam->handle, cam->device);
197 }
198 
199 
campause(s_cam * cam)200 void campause(s_cam *cam) {
201   avc1394_vcr_pause(cam->handle, cam->device);
202 }
203 
204 
cameject(s_cam * cam)205 void cameject(s_cam *cam) {
206   avc1394_vcr_eject(cam->handle, cam->device);
207 }
208 
209 
210 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
211 
find_free_camfile(int format)212 char *find_free_camfile(int format) {
213   char *filename = lives_strdup(lives_entry_get_text(LIVES_ENTRY(dvgrabw->filent)));
214   char *fname, *tmp = NULL, *tmp2, *tmp3;
215 
216   register int i;
217 
218   if (format == CAM_FORMAT_HDV) {
219     for (i = 1; i < 10000; i++) {
220       fname = lives_strdup_printf("%s%04d.mpg", filename, i);
221       if (!lives_file_test((tmp = lives_build_filename((tmp2 = lives_filename_from_utf8(dvgrabw->dirname, -1, NULL, NULL, NULL)),
222                                   (tmp3 = lives_filename_from_utf8(fname, -1, NULL, NULL, NULL)), NULL)),
223                            LIVES_FILE_TEST_EXISTS)) break;
224       lives_free(tmp);
225       lives_free(tmp2);
226       lives_free(tmp3);
227       tmp = NULL;
228     }
229   } else {
230     for (i = 1; i < 1000; i++) {
231       fname = lives_strdup_printf("%s%03d.dv", filename, i);
232       if (!lives_file_test((tmp = lives_build_filename((tmp2 = lives_filename_from_utf8(dvgrabw->dirname, -1, NULL, NULL, NULL)),
233                                   (tmp3 = lives_filename_from_utf8(fname, -1, NULL, NULL, NULL)), NULL)),
234                            LIVES_FILE_TEST_EXISTS)) break;
235       lives_free(tmp);
236       lives_free(tmp2);
237       lives_free(tmp3);
238       tmp = NULL;
239     }
240   }
241   if (tmp) lives_free(tmp);
242   lives_free(filename);
243 
244   return fname;
245 }
246 
247 
rec(s_cam * cam)248 boolean rec(s_cam *cam) {
249   // returns filename of file being written
250 
251   char *tmp2, *tmp3, *com;
252   char *splits;
253 
254   if (cam->pgid != 0) return FALSE;
255 
256   if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(dvgrabw->split))) splits = lives_strdup("-autosplit ");
257   else splits = lives_strdup("");
258 
259   if (cam->format == CAM_FORMAT_DV) {
260     // dv format
261 #ifndef IS_MINGW
262     com = lives_strdup_printf("dvgrab -format raw %s\"%s/%s\" >/dev/null 2>&1 &", splits,
263                               (tmp2 = lives_filename_from_utf8(dvgrabw->dirname, -1, NULL, NULL, NULL)),
264                               (tmp3 = lives_filename_from_utf8(dvgrabw->filename, -1, NULL, NULL, NULL)));
265 #else
266     com = lives_strdup_printf("dvgrab.exe -format raw %s\"%s\\%s\" >NUL 2>&1 &", splits,
267                               (tmp2 = lives_filename_from_utf8(dvgrabw->dirname, -1, NULL, NULL, NULL)),
268                               (tmp3 = lives_filename_from_utf8(dvgrabw->filename, -1, NULL, NULL, NULL)));
269 #endif
270     cam->pgid = lives_fork(com);
271     lives_free(com);
272     lives_free(tmp2);
273     lives_free(tmp3);
274     lives_free(splits);
275     return TRUE;
276   }
277 
278   // hdv format
279 #ifndef IS_MINGW
280   com = lives_strdup_printf("dvgrab -format mpeg2 %s\"%s/%s\" >/dev/null 2>&1 &", splits,
281                             (tmp2 = lives_filename_from_utf8(dvgrabw->dirname, -1, NULL, NULL, NULL)),
282                             (tmp3 = lives_filename_from_utf8(dvgrabw->filename, -1, NULL, NULL, NULL)));
283 #else
284   com = lives_strdup_printf("dvgrab.exe -format mpeg2 %s\"%s\\%s\" >NUL 2>&1 &", splits,
285                             (tmp2 = lives_filename_from_utf8(dvgrabw->dirname, -1, NULL, NULL, NULL)),
286                             (tmp3 = lives_filename_from_utf8(dvgrabw->filename, -1, NULL, NULL, NULL)));
287 #endif
288 
289   cam->pgid = lives_fork(com);
290 
291   lives_free(com);
292   lives_free(tmp2);
293   lives_free(tmp3);
294   lives_free(splits);
295 
296   return TRUE;
297 }
298 
299 
on_open_fw_activate(LiVESMenuItem * menuitem,livespointer user_data)300 void on_open_fw_activate(LiVESMenuItem *menuitem, livespointer user_data) {
301   int type = LIVES_POINTER_TO_INT(user_data); // type 0==dv, type 1==hdv
302   s_cam *cam;
303 
304   if (!capable->has_mplayer && !capable->has_mplayer2) {
305     do_need_mplayer_dialog();
306     return;
307   }
308 
309   if (type == CAM_FORMAT_DV && !capable->has_dvgrab) {
310     do_dvgrab_error();
311     return;
312   }
313 
314   cam = camready();
315   if (!cam) return;
316 
317   /*  if (type==CAM_FORMAT_HDV) {
318     cam->rec_handle=open_raw1394();
319     if (cam->rec_handle==NULL) return;
320     }
321     else*/
322   cam->rec_handle = NULL;
323 
324   if (mainw->multitrack) {
325     if (mainw->multitrack->idlefunc > 0) {
326       lives_source_remove(mainw->multitrack->idlefunc);
327       mainw->multitrack->idlefunc = 0;
328     }
329     mt_desensitise(mainw->multitrack);
330   }
331 
332   dvgrabw = create_camwindow(cam, type);
333   lives_widget_show_all(dvgrabw->dialog);
334   dvgrabw->cursor = NULL;
335   cam->format = type;
336   cam->grabbed_clips = FALSE;
337   cam->pgid = 0;
338   dvgrabw->cam = cam;
339 }
340 
341