4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "playbackconfig.h"
26 #include "preferences.h"
27 #include "recordconfig.h"
28 #include "strategies.inc"
29 #include "vdevicelml.h"
31 #include "videoconfig.h"
32 #include "videodevice.h"
41 VDeviceLML::VDeviceLML(VideoDevice *device)
45 render_strategies.append(VRENDER_MJPG);
48 VDeviceLML::~VDeviceLML()
53 int VDeviceLML::reset_parameters()
61 input_position = INPUT_BUFFER_SIZE;
65 int VDeviceLML::open_input()
67 jvideo_fd = fopen(device->in_config->lml_in_device, "rb");
74 perror("VDeviceLML::open_input");
81 int VDeviceLML::open_output()
83 jvideo_fd = fopen(device->out_config->lml_out_device, "wb");
90 perror("VDeviceLML::open_output");
97 int VDeviceLML::close_all()
101 if(jvideo_fd) fclose(jvideo_fd);
105 if(jvideo_fd) fclose(jvideo_fd);
119 int VDeviceLML::read_buffer(VFrame *frame)
121 long first_field = 0, frame1_size = 0, frame2_size = 0, i;
122 int result = 0, frame_no = 0, retries = 0;
124 if(!jvideo_fd) return 1;
129 frame->set_compressed_size(0);
131 if(retries > 5) return 1;
133 // Keep reading until the first field of a frame arrives.
134 while(!input_error && !first_field)
136 // Get the first marker of a frame
137 while(!input_error && next_bytes(2) != SOI)
144 write_byte(get_byte());
145 write_byte(get_byte());
147 // Copy the first frame
148 while(!input_error && next_bytes(2) != EOI)
150 // Replace the LML header with a Quicktime header
151 if(next_bytes(2) == APP3)
160 get_byte(); // COMMENT
164 get_byte(); // Frame no
174 get_byte(); // framesize (useless since we have to swap frames)
178 frame_no = get_byte(); // frame seq no
179 frame_no |= (long)get_byte() << 8;
180 frame_no |= (long)get_byte() << 16;
181 frame_no |= (long)get_byte() << 24;
183 if(frame_no <= last_frame_no)
185 input_error = reopen_input();
192 last_frame_no = frame_no;
193 while(next_bytes(2) != 0xffdb) get_byte();
198 write_byte(get_byte());
203 write_byte(get_byte());
204 write_byte(get_byte());
207 frame1_size = frame_size;
209 // Read the second field
213 while(!input_error && next_bytes(2) != SOI)
219 write_byte(get_byte());
220 write_byte(get_byte());
222 // Store Quicktime header
225 // Copy the second frame
226 while(!input_error && next_bytes(2) != EOI)
228 write_byte(get_byte());
232 write_byte(get_byte());
233 write_byte(get_byte());
236 frame2_size = frame_size - frame1_size;
238 // Insert the required information
241 // quicktime_fixmarker_jpeg(&jpeg_header, (char*)frame_buffer, frame1_size, !device->odd_field_first);
242 // quicktime_fixmarker_jpeg(&jpeg_header, (char*)frame_buffer + frame1_size, frame2_size, device->odd_field_first);
244 // Store in the VFrame
245 frame->allocate_compressed_data(frame_size);
247 // Quicktime expects the even field first
248 if(device->odd_field_first)
250 memcpy(frame->get_data(), frame_buffer + frame1_size, frame2_size);
251 memcpy(frame->get_data() + frame2_size, frame_buffer, frame1_size);
254 memcpy(frame->get_data(), frame_buffer, frame_size);
256 frame->set_compressed_size(frame_size);
268 int VDeviceLML::reopen_input()
272 fprintf(stderr, _("VDeviceLML::read_buffer: driver crash\n"));
275 input_error = open_input();
276 if(!input_error) fprintf(stderr, _("VDeviceLML::read_buffer: reopened\n"));
278 input_position = INPUT_BUFFER_SIZE;
283 int VDeviceLML::write_fake_marker()
292 for(int i = 0; i < 0x28; i++)
299 int VDeviceLML::refill_input()
301 // Shift remaining data up.
302 memcpy(input_buffer, input_buffer + input_position, INPUT_BUFFER_SIZE - input_position);
305 input_error = !fread(input_buffer + INPUT_BUFFER_SIZE - input_position,
306 INPUT_BUFFER_SIZE - (INPUT_BUFFER_SIZE - input_position),
315 int VDeviceLML::write_buffer(VFrame *frame, EDL *edl)
317 int result = 0, i, frame1size, j, size_qword, real_size, skip;
318 unsigned long size = frame->get_compressed_size();
319 unsigned char *data = frame->get_data();
320 unsigned char *data1;
321 int even_field_first = 1;
324 if(!jvideo_fd || frame->get_color_model() != VFRAME_COMPRESSED) return 1;
327 if(frame_allocated < size * 2)
335 frame_buffer = new unsigned char[size * 2];
338 for(data1 = data + 1, i = 0; i < size - 1; i++)
339 if(data[i] == ((EOI & 0xff00) >> 8) && data1[i] == (EOI & 0xff)) break;
344 if(even_field_first) i = 0;
347 frame_buffer[j++] = data[i++];
348 frame_buffer[j++] = data[i++];
350 // APP3 for LML driver
351 frame_buffer[j++] = (APP3 & 0xff00) >> 8;
352 frame_buffer[j++] = APP3 & 0xff;
353 frame_buffer[j++] = 0; // Marker size
354 frame_buffer[j++] = 0x2c;
355 frame_buffer[j++] = 'L'; // nm
356 frame_buffer[j++] = 'M';
357 frame_buffer[j++] = 'L';
358 frame_buffer[j++] = 0;
359 frame_buffer[j++] = 0; // frameNo
360 frame_buffer[j++] = 0;
361 frame_buffer[j++] = 0; // sec
362 frame_buffer[j++] = 0;
363 frame_buffer[j++] = 0;
364 frame_buffer[j++] = 0;
365 frame_buffer[j++] = 0; // usec
366 frame_buffer[j++] = 0;
367 frame_buffer[j++] = 0;
368 frame_buffer[j++] = 0;
369 // Frame size eventually goes here
371 frame_buffer[j++] = 0;
372 frame_buffer[j++] = 0;
373 frame_buffer[j++] = 0;
374 frame_buffer[j++] = 0;
376 frame_buffer[j++] = 0;
377 frame_buffer[j++] = 0;
378 frame_buffer[j++] = 0;
379 frame_buffer[j++] = 0;
381 frame_buffer[j++] = 1;
382 frame_buffer[j++] = 0;
383 frame_buffer[j++] = 0;
384 frame_buffer[j++] = 0;
386 frame_buffer[j++] = 1;
387 frame_buffer[j++] = 0;
388 frame_buffer[j++] = 0;
389 frame_buffer[j++] = 0;
391 frame_buffer[j++] = 1;
392 frame_buffer[j++] = 0;
394 frame_buffer[j++] = 0;
395 frame_buffer[j++] = 0;
396 frame_buffer[j++] = 0;
397 frame_buffer[j++] = 0;
398 frame_buffer[j++] = 0;
399 frame_buffer[j++] = 0;
400 frame_buffer[j++] = 0;
401 frame_buffer[j++] = 0;
402 frame_buffer[j++] = 0;
403 frame_buffer[j++] = 0;
405 // Copy rest of first field
410 frame_buffer[j++] = data[i++];
414 if(!even_field_first)
416 for(i = 0; i < frame1size; )
418 frame_buffer[j++] = data[i++];
423 // frameSize in little endian
424 frame_buffer[size_qword++] = (real_size & 0xff);
425 frame_buffer[size_qword++] = ((real_size & 0xff00) >> 8);
426 frame_buffer[size_qword++] = ((real_size & 0xff0000) >> 16);
427 frame_buffer[size_qword++] = ((real_size & 0xff000000) >> 24);
429 //fwrite(frame_buffer, real_size, 1, stdout);
430 result = !fwrite(frame_buffer,
434 if(result) perror("VDeviceLML::write_buffer");
439 ArrayList<int>* VDeviceLML::get_render_strategies()
441 return &render_strategies;