4 #include "playbackconfig.h"
5 #include "preferences.h"
6 #include "recordconfig.h"
7 #include "strategies.inc"
8 #include "vdevicelml.h"
10 #include "videoconfig.h"
11 #include "videodevice.h"
20 VDeviceLML::VDeviceLML(VideoDevice *device)
24 render_strategies.append(VRENDER_MJPG);
27 VDeviceLML::~VDeviceLML()
32 int VDeviceLML::reset_parameters()
40 input_position = INPUT_BUFFER_SIZE;
44 int VDeviceLML::open_input()
46 jvideo_fd = fopen(device->in_config->lml_in_device, "rb");
53 perror("VDeviceLML::open_input");
60 int VDeviceLML::open_output()
62 jvideo_fd = fopen(device->out_config->lml_out_device, "wb");
69 perror("VDeviceLML::open_output");
76 int VDeviceLML::close_all()
80 if(jvideo_fd) fclose(jvideo_fd);
84 if(jvideo_fd) fclose(jvideo_fd);
98 int VDeviceLML::read_buffer(VFrame *frame)
100 long first_field = 0, frame1_size = 0, frame2_size = 0, i;
101 int result = 0, frame_no = 0, retries = 0;
103 if(!jvideo_fd) return 1;
108 frame->set_compressed_size(0);
110 if(retries > 5) return 1;
112 // Keep reading until the first field of a frame arrives.
113 while(!input_error && !first_field)
115 // Get the first marker of a frame
116 while(!input_error && next_bytes(2) != SOI)
123 write_byte(get_byte());
124 write_byte(get_byte());
126 // Copy the first frame
127 while(!input_error && next_bytes(2) != EOI)
129 // Replace the LML header with a Quicktime header
130 if(next_bytes(2) == APP3)
139 get_byte(); // COMMENT
143 get_byte(); // Frame no
153 get_byte(); // framesize (useless since we have to swap frames)
157 frame_no = get_byte(); // frame seq no
158 frame_no |= (long)get_byte() << 8;
159 frame_no |= (long)get_byte() << 16;
160 frame_no |= (long)get_byte() << 24;
162 if(frame_no <= last_frame_no)
164 input_error = reopen_input();
171 last_frame_no = frame_no;
172 while(next_bytes(2) != 0xffdb) get_byte();
177 write_byte(get_byte());
182 write_byte(get_byte());
183 write_byte(get_byte());
186 frame1_size = frame_size;
188 // Read the second field
192 while(!input_error && next_bytes(2) != SOI)
198 write_byte(get_byte());
199 write_byte(get_byte());
201 // Store Quicktime header
204 // Copy the second frame
205 while(!input_error && next_bytes(2) != EOI)
207 write_byte(get_byte());
211 write_byte(get_byte());
212 write_byte(get_byte());
215 frame2_size = frame_size - frame1_size;
217 // Insert the required information
220 // quicktime_fixmarker_jpeg(&jpeg_header, (char*)frame_buffer, frame1_size, !device->odd_field_first);
221 // quicktime_fixmarker_jpeg(&jpeg_header, (char*)frame_buffer + frame1_size, frame2_size, device->odd_field_first);
223 // Store in the VFrame
224 frame->allocate_compressed_data(frame_size);
226 // Quicktime expects the even field first
227 if(device->odd_field_first)
229 memcpy(frame->get_data(), frame_buffer + frame1_size, frame2_size);
230 memcpy(frame->get_data() + frame2_size, frame_buffer, frame1_size);
233 memcpy(frame->get_data(), frame_buffer, frame_size);
235 frame->set_compressed_size(frame_size);
247 int VDeviceLML::reopen_input()
251 fprintf(stderr, _("VDeviceLML::read_buffer: driver crash\n"));
254 input_error = open_input();
255 if(!input_error) fprintf(stderr, _("VDeviceLML::read_buffer: reopened\n"));
257 input_position = INPUT_BUFFER_SIZE;
262 int VDeviceLML::write_fake_marker()
271 for(int i = 0; i < 0x28; i++)
278 int VDeviceLML::refill_input()
280 // Shift remaining data up.
281 memcpy(input_buffer, input_buffer + input_position, INPUT_BUFFER_SIZE - input_position);
284 input_error = !fread(input_buffer + INPUT_BUFFER_SIZE - input_position,
285 INPUT_BUFFER_SIZE - (INPUT_BUFFER_SIZE - input_position),
294 int VDeviceLML::write_buffer(VFrame *frame, EDL *edl)
296 int result = 0, i, frame1size, j, size_qword, real_size, skip;
297 unsigned long size = frame->get_compressed_size();
298 unsigned char *data = frame->get_data();
299 unsigned char *data1;
300 int even_field_first = 1;
303 if(!jvideo_fd || frame->get_color_model() != VFRAME_COMPRESSED) return 1;
306 if(frame_allocated < size * 2)
314 frame_buffer = new unsigned char[size * 2];
317 for(data1 = data + 1, i = 0; i < size - 1; i++)
318 if(data[i] == ((EOI & 0xff00) >> 8) && data1[i] == (EOI & 0xff)) break;
323 if(even_field_first) i = 0;
326 frame_buffer[j++] = data[i++];
327 frame_buffer[j++] = data[i++];
329 // APP3 for LML driver
330 frame_buffer[j++] = (APP3 & 0xff00) >> 8;
331 frame_buffer[j++] = APP3 & 0xff;
332 frame_buffer[j++] = 0; // Marker size
333 frame_buffer[j++] = 0x2c;
334 frame_buffer[j++] = 'L'; // nm
335 frame_buffer[j++] = 'M';
336 frame_buffer[j++] = 'L';
337 frame_buffer[j++] = 0;
338 frame_buffer[j++] = 0; // frameNo
339 frame_buffer[j++] = 0;
340 frame_buffer[j++] = 0; // sec
341 frame_buffer[j++] = 0;
342 frame_buffer[j++] = 0;
343 frame_buffer[j++] = 0;
344 frame_buffer[j++] = 0; // usec
345 frame_buffer[j++] = 0;
346 frame_buffer[j++] = 0;
347 frame_buffer[j++] = 0;
348 // Frame size eventually goes here
350 frame_buffer[j++] = 0;
351 frame_buffer[j++] = 0;
352 frame_buffer[j++] = 0;
353 frame_buffer[j++] = 0;
355 frame_buffer[j++] = 0;
356 frame_buffer[j++] = 0;
357 frame_buffer[j++] = 0;
358 frame_buffer[j++] = 0;
360 frame_buffer[j++] = 1;
361 frame_buffer[j++] = 0;
362 frame_buffer[j++] = 0;
363 frame_buffer[j++] = 0;
365 frame_buffer[j++] = 1;
366 frame_buffer[j++] = 0;
367 frame_buffer[j++] = 0;
368 frame_buffer[j++] = 0;
370 frame_buffer[j++] = 1;
371 frame_buffer[j++] = 0;
373 frame_buffer[j++] = 0;
374 frame_buffer[j++] = 0;
375 frame_buffer[j++] = 0;
376 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;
384 // Copy rest of first field
389 frame_buffer[j++] = data[i++];
393 if(!even_field_first)
395 for(i = 0; i < frame1size; )
397 frame_buffer[j++] = data[i++];
402 // frameSize in little endian
403 frame_buffer[size_qword++] = (real_size & 0xff);
404 frame_buffer[size_qword++] = ((real_size & 0xff00) >> 8);
405 frame_buffer[size_qword++] = ((real_size & 0xff0000) >> 16);
406 frame_buffer[size_qword++] = ((real_size & 0xff000000) >> 24);
408 //fwrite(frame_buffer, real_size, 1, stdout);
409 result = !fwrite(frame_buffer,
413 if(result) perror("VDeviceLML::write_buffer");
418 ArrayList<int>* VDeviceLML::get_render_strategies()
420 return &render_strategies;
425 // c-file-style: "linux"