3 #include "playbackconfig.h"
4 #include "preferences.h"
5 #include "recordconfig.h"
6 #include "strategies.inc"
7 #include "vdevicelml.h"
9 #include "videoconfig.h"
10 #include "videodevice.h"
13 #define _(String) gettext(String)
14 #define gettext_noop(String) String
15 #define N_(String) gettext_noop (String)
24 VDeviceLML::VDeviceLML(VideoDevice *device)
28 render_strategies.append(VRENDER_MJPG);
31 VDeviceLML::~VDeviceLML()
36 int VDeviceLML::reset_parameters()
44 input_position = INPUT_BUFFER_SIZE;
48 int VDeviceLML::open_input()
50 jvideo_fd = fopen(device->in_config->lml_in_device, "rb");
57 perror("VDeviceLML::open_input");
64 int VDeviceLML::open_output()
66 jvideo_fd = fopen(device->out_config->lml_out_device, "wb");
73 perror("VDeviceLML::open_output");
80 int VDeviceLML::close_all()
84 if(jvideo_fd) fclose(jvideo_fd);
88 if(jvideo_fd) fclose(jvideo_fd);
102 int VDeviceLML::read_buffer(VFrame *frame)
104 long first_field = 0, frame1_size = 0, frame2_size = 0, i;
105 int result = 0, frame_no = 0, retries = 0;
107 if(!jvideo_fd) return 1;
112 frame->set_compressed_size(0);
114 if(retries > 5) return 1;
116 // Keep reading until the first field of a frame arrives.
117 while(!input_error && !first_field)
119 // Get the first marker of a frame
120 while(!input_error && next_bytes(2) != SOI)
127 write_byte(get_byte());
128 write_byte(get_byte());
130 // Copy the first frame
131 while(!input_error && next_bytes(2) != EOI)
133 // Replace the LML header with a Quicktime header
134 if(next_bytes(2) == APP3)
143 get_byte(); // COMMENT
147 get_byte(); // Frame no
157 get_byte(); // framesize (useless since we have to swap frames)
161 frame_no = get_byte(); // frame seq no
162 frame_no |= (long)get_byte() << 8;
163 frame_no |= (long)get_byte() << 16;
164 frame_no |= (long)get_byte() << 24;
166 if(frame_no <= last_frame_no)
168 input_error = reopen_input();
175 last_frame_no = frame_no;
176 while(next_bytes(2) != 0xffdb) get_byte();
181 write_byte(get_byte());
186 write_byte(get_byte());
187 write_byte(get_byte());
190 frame1_size = frame_size;
192 // Read the second field
196 while(!input_error && next_bytes(2) != SOI)
202 write_byte(get_byte());
203 write_byte(get_byte());
205 // Store Quicktime header
208 // Copy the second frame
209 while(!input_error && next_bytes(2) != EOI)
211 write_byte(get_byte());
215 write_byte(get_byte());
216 write_byte(get_byte());
219 frame2_size = frame_size - frame1_size;
221 // Insert the required information
224 // quicktime_fixmarker_jpeg(&jpeg_header, (char*)frame_buffer, frame1_size, !device->odd_field_first);
225 // quicktime_fixmarker_jpeg(&jpeg_header, (char*)frame_buffer + frame1_size, frame2_size, device->odd_field_first);
227 // Store in the VFrame
228 frame->allocate_compressed_data(frame_size);
230 // Quicktime expects the even field first
231 if(device->odd_field_first)
233 memcpy(frame->get_data(), frame_buffer + frame1_size, frame2_size);
234 memcpy(frame->get_data() + frame2_size, frame_buffer, frame1_size);
237 memcpy(frame->get_data(), frame_buffer, frame_size);
239 frame->set_compressed_size(frame_size);
251 int VDeviceLML::reopen_input()
255 fprintf(stderr, _("VDeviceLML::read_buffer: driver crash\n"));
258 input_error = open_input();
259 if(!input_error) fprintf(stderr, _("VDeviceLML::read_buffer: reopened\n"));
261 input_position = INPUT_BUFFER_SIZE;
266 int VDeviceLML::write_fake_marker()
275 for(int i = 0; i < 0x28; i++)
282 int VDeviceLML::refill_input()
284 // Shift remaining data up.
285 memcpy(input_buffer, input_buffer + input_position, INPUT_BUFFER_SIZE - input_position);
288 input_error = !fread(input_buffer + INPUT_BUFFER_SIZE - input_position,
289 INPUT_BUFFER_SIZE - (INPUT_BUFFER_SIZE - input_position),
298 int VDeviceLML::write_buffer(VFrame *frame, EDL *edl)
300 int result = 0, i, frame1size, j, size_qword, real_size, skip;
301 unsigned long size = frame->get_compressed_size();
302 unsigned char *data = frame->get_data();
303 unsigned char *data1;
304 int even_field_first = 1;
307 if(!jvideo_fd || frame->get_color_model() != VFRAME_COMPRESSED) return 1;
310 if(frame_allocated < size * 2)
318 frame_buffer = new unsigned char[size * 2];
321 for(data1 = data + 1, i = 0; i < size - 1; i++)
322 if(data[i] == ((EOI & 0xff00) >> 8) && data1[i] == (EOI & 0xff)) break;
327 if(even_field_first) i = 0;
330 frame_buffer[j++] = data[i++];
331 frame_buffer[j++] = data[i++];
333 // APP3 for LML driver
334 frame_buffer[j++] = (APP3 & 0xff00) >> 8;
335 frame_buffer[j++] = APP3 & 0xff;
336 frame_buffer[j++] = 0; // Marker size
337 frame_buffer[j++] = 0x2c;
338 frame_buffer[j++] = 'L'; // nm
339 frame_buffer[j++] = 'M';
340 frame_buffer[j++] = 'L';
341 frame_buffer[j++] = 0;
342 frame_buffer[j++] = 0; // frameNo
343 frame_buffer[j++] = 0;
344 frame_buffer[j++] = 0; // sec
345 frame_buffer[j++] = 0;
346 frame_buffer[j++] = 0;
347 frame_buffer[j++] = 0;
348 frame_buffer[j++] = 0; // usec
349 frame_buffer[j++] = 0;
350 frame_buffer[j++] = 0;
351 frame_buffer[j++] = 0;
352 // Frame size eventually goes here
354 frame_buffer[j++] = 0;
355 frame_buffer[j++] = 0;
356 frame_buffer[j++] = 0;
357 frame_buffer[j++] = 0;
359 frame_buffer[j++] = 0;
360 frame_buffer[j++] = 0;
361 frame_buffer[j++] = 0;
362 frame_buffer[j++] = 0;
364 frame_buffer[j++] = 1;
365 frame_buffer[j++] = 0;
366 frame_buffer[j++] = 0;
367 frame_buffer[j++] = 0;
369 frame_buffer[j++] = 1;
370 frame_buffer[j++] = 0;
371 frame_buffer[j++] = 0;
372 frame_buffer[j++] = 0;
374 frame_buffer[j++] = 1;
375 frame_buffer[j++] = 0;
377 frame_buffer[j++] = 0;
378 frame_buffer[j++] = 0;
379 frame_buffer[j++] = 0;
380 frame_buffer[j++] = 0;
381 frame_buffer[j++] = 0;
382 frame_buffer[j++] = 0;
383 frame_buffer[j++] = 0;
384 frame_buffer[j++] = 0;
385 frame_buffer[j++] = 0;
386 frame_buffer[j++] = 0;
388 // Copy rest of first field
393 frame_buffer[j++] = data[i++];
397 if(!even_field_first)
399 for(i = 0; i < frame1size; )
401 frame_buffer[j++] = data[i++];
406 // frameSize in little endian
407 frame_buffer[size_qword++] = (real_size & 0xff);
408 frame_buffer[size_qword++] = ((real_size & 0xff00) >> 8);
409 frame_buffer[size_qword++] = ((real_size & 0xff0000) >> 16);
410 frame_buffer[size_qword++] = ((real_size & 0xff000000) >> 24);
412 //fwrite(frame_buffer, real_size, 1, stdout);
413 result = !fwrite(frame_buffer,
417 if(result) perror("VDeviceLML::write_buffer");
422 ArrayList<int>* VDeviceLML::get_render_strategies()
424 return &render_strategies;