00001 #include "assets.h"
00002 #include "file.inc"
00003 #include "language.h"
00004 #include "playbackconfig.h"
00005 #include "preferences.h"
00006 #include "recordconfig.h"
00007 #include "strategies.inc"
00008 #include "vdevicelml.h"
00009 #include "vframe.h"
00010 #include "videoconfig.h"
00011 #include "videodevice.h"
00012
00013
00014 #define SOI 0xffd8
00015 #define APP3 0xffe3
00016 #define APP1 0xffe1
00017 #define APP0 0xffe0
00018 #define EOI 0xffd9
00019
00020 VDeviceLML::VDeviceLML(VideoDevice *device)
00021 : VDeviceBase(device)
00022 {
00023 reset_parameters();
00024 render_strategies.append(VRENDER_MJPG);
00025 }
00026
00027 VDeviceLML::~VDeviceLML()
00028 {
00029 close_all();
00030 }
00031
00032 int VDeviceLML::reset_parameters()
00033 {
00034 jvideo_fd = 0;
00035 input_buffer = 0;
00036 frame_buffer = 0;
00037 frame_size = 0;
00038 frame_allocated = 0;
00039 input_error = 0;
00040 input_position = INPUT_BUFFER_SIZE;
00041 last_frame_no = 0;
00042 }
00043
00044 int VDeviceLML::open_input()
00045 {
00046 jvideo_fd = fopen(device->in_config->lml_in_device, "rb");
00047 if(jvideo_fd)
00048 {
00049 return 0;
00050 }
00051 else
00052 {
00053 perror("VDeviceLML::open_input");
00054 jvideo_fd = 0;
00055 return 1;
00056 }
00057 return 0;
00058 }
00059
00060 int VDeviceLML::open_output()
00061 {
00062 jvideo_fd = fopen(device->out_config->lml_out_device, "wb");
00063 if(jvideo_fd)
00064 {
00065 return 0;
00066 }
00067 else
00068 {
00069 perror("VDeviceLML::open_output");
00070 jvideo_fd = 0;
00071 return 1;
00072 }
00073 return 0;
00074 }
00075
00076 int VDeviceLML::close_all()
00077 {
00078 if(device->r)
00079 {
00080 if(jvideo_fd) fclose(jvideo_fd);
00081 }
00082 if(device->w)
00083 {
00084 if(jvideo_fd) fclose(jvideo_fd);
00085 }
00086 if(input_buffer)
00087 {
00088 delete input_buffer;
00089 }
00090 if(frame_buffer)
00091 {
00092 delete frame_buffer;
00093 }
00094 reset_parameters();
00095 return 0;
00096 }
00097
00098 int VDeviceLML::read_buffer(VFrame *frame)
00099 {
00100 long first_field = 0, frame1_size = 0, frame2_size = 0, i;
00101 int result = 0, frame_no = 0, retries = 0;
00102
00103 if(!jvideo_fd) return 1;
00104
00105 input_error = 0;
00106
00107 retry:
00108 frame->set_compressed_size(0);
00109 retries++;
00110 if(retries > 5) return 1;
00111
00112
00113 while(!input_error && !first_field)
00114 {
00115
00116 while(!input_error && next_bytes(2) != SOI)
00117 {
00118 get_byte();
00119 }
00120
00121
00122 frame_size = 0;
00123 write_byte(get_byte());
00124 write_byte(get_byte());
00125
00126
00127 while(!input_error && next_bytes(2) != EOI)
00128 {
00129
00130 if(next_bytes(2) == APP3)
00131 {
00132 first_field = 1;
00133 write_fake_marker();
00134
00135 get_byte();
00136 get_byte();
00137 get_byte();
00138 get_byte();
00139 get_byte();
00140 get_byte();
00141 get_byte();
00142 get_byte();
00143 get_byte();
00144 get_byte();
00145 get_byte();
00146 get_byte();
00147 get_byte();
00148 get_byte();
00149 get_byte();
00150 get_byte();
00151 get_byte();
00152 get_byte();
00153 get_byte();
00154 get_byte();
00155 get_byte();
00156 get_byte();
00157 frame_no = get_byte();
00158 frame_no |= (long)get_byte() << 8;
00159 frame_no |= (long)get_byte() << 16;
00160 frame_no |= (long)get_byte() << 24;
00161
00162 if(frame_no <= last_frame_no)
00163 {
00164 input_error = reopen_input();
00165 first_field = 0;
00166 goto retry;
00167 }
00168 else
00169 {
00170
00171 last_frame_no = frame_no;
00172 while(next_bytes(2) != 0xffdb) get_byte();
00173 }
00174 }
00175 else
00176 {
00177 write_byte(get_byte());
00178 }
00179 }
00180
00181
00182 write_byte(get_byte());
00183 write_byte(get_byte());
00184 }
00185
00186 frame1_size = frame_size;
00187
00188
00189 if(first_field)
00190 {
00191
00192 while(!input_error && next_bytes(2) != SOI)
00193 {
00194 get_byte();
00195 }
00196
00197
00198 write_byte(get_byte());
00199 write_byte(get_byte());
00200
00201
00202 write_fake_marker();
00203
00204
00205 while(!input_error && next_bytes(2) != EOI)
00206 {
00207 write_byte(get_byte());
00208 }
00209
00210
00211 write_byte(get_byte());
00212 write_byte(get_byte());
00213 }
00214
00215 frame2_size = frame_size - frame1_size;
00216
00217
00218 if(!input_error)
00219 {
00220
00221
00222
00223
00224 frame->allocate_compressed_data(frame_size);
00225
00226
00227 if(device->odd_field_first)
00228 {
00229 memcpy(frame->get_data(), frame_buffer + frame1_size, frame2_size);
00230 memcpy(frame->get_data() + frame2_size, frame_buffer, frame1_size);
00231 }
00232 else
00233 memcpy(frame->get_data(), frame_buffer, frame_size);
00234
00235 frame->set_compressed_size(frame_size);
00236 }
00237 else
00238 {
00239 input_error = 0;
00240 reopen_input();
00241 goto retry;
00242 }
00243
00244 return input_error;
00245 }
00246
00247 int VDeviceLML::reopen_input()
00248 {
00249 int input_error = 0;
00250 Timer timer;
00251 fprintf(stderr, _("VDeviceLML::read_buffer: driver crash\n"));
00252 fclose(jvideo_fd);
00253 timer.delay(100);
00254 input_error = open_input();
00255 if(!input_error) fprintf(stderr, _("VDeviceLML::read_buffer: reopened\n"));
00256 last_frame_no = 0;
00257 input_position = INPUT_BUFFER_SIZE;
00258 return input_error;
00259 }
00260
00261
00262 int VDeviceLML::write_fake_marker()
00263 {
00264
00265 write_byte(0xff);
00266 write_byte(0xe1);
00267
00268 write_byte(0x00);
00269 write_byte(0x2a);
00270
00271 for(int i = 0; i < 0x28; i++)
00272 {
00273 write_byte(0x00);
00274 }
00275 return 0;
00276 }
00277
00278 int VDeviceLML::refill_input()
00279 {
00280
00281 memcpy(input_buffer, input_buffer + input_position, INPUT_BUFFER_SIZE - input_position);
00282
00283
00284 input_error = !fread(input_buffer + INPUT_BUFFER_SIZE - input_position,
00285 INPUT_BUFFER_SIZE - (INPUT_BUFFER_SIZE - input_position),
00286 1,
00287 jvideo_fd);
00288
00289 input_position = 0;
00290 return input_error;
00291 }
00292
00293
00294 int VDeviceLML::write_buffer(VFrame *frame, EDL *edl)
00295 {
00296 int result = 0, i, frame1size, j, size_qword, real_size, skip;
00297 unsigned long size = frame->get_compressed_size();
00298 unsigned char *data = frame->get_data();
00299 unsigned char *data1;
00300 int even_field_first = 1;
00301
00302 #if 0
00303 if(!jvideo_fd || frame->get_color_model() != VFRAME_COMPRESSED) return 1;
00304 #endif
00305
00306 if(frame_allocated < size * 2)
00307 {
00308 delete frame_buffer;
00309 frame_buffer = 0;
00310 }
00311
00312 if(!frame_buffer)
00313 {
00314 frame_buffer = new unsigned char[size * 2];
00315 }
00316
00317 for(data1 = data + 1, i = 0; i < size - 1; i++)
00318 if(data[i] == ((EOI & 0xff00) >> 8) && data1[i] == (EOI & 0xff)) break;
00319
00320 i += 2;
00321 frame1size = i;
00322 j = 0;
00323 if(even_field_first) i = 0;
00324
00325
00326 frame_buffer[j++] = data[i++];
00327 frame_buffer[j++] = data[i++];
00328
00329
00330 frame_buffer[j++] = (APP3 & 0xff00) >> 8;
00331 frame_buffer[j++] = APP3 & 0xff;
00332 frame_buffer[j++] = 0;
00333 frame_buffer[j++] = 0x2c;
00334 frame_buffer[j++] = 'L';
00335 frame_buffer[j++] = 'M';
00336 frame_buffer[j++] = 'L';
00337 frame_buffer[j++] = 0;
00338 frame_buffer[j++] = 0;
00339 frame_buffer[j++] = 0;
00340 frame_buffer[j++] = 0;
00341 frame_buffer[j++] = 0;
00342 frame_buffer[j++] = 0;
00343 frame_buffer[j++] = 0;
00344 frame_buffer[j++] = 0;
00345 frame_buffer[j++] = 0;
00346 frame_buffer[j++] = 0;
00347 frame_buffer[j++] = 0;
00348
00349 size_qword = j;
00350 frame_buffer[j++] = 0;
00351 frame_buffer[j++] = 0;
00352 frame_buffer[j++] = 0;
00353 frame_buffer[j++] = 0;
00354
00355 frame_buffer[j++] = 0;
00356 frame_buffer[j++] = 0;
00357 frame_buffer[j++] = 0;
00358 frame_buffer[j++] = 0;
00359
00360 frame_buffer[j++] = 1;
00361 frame_buffer[j++] = 0;
00362 frame_buffer[j++] = 0;
00363 frame_buffer[j++] = 0;
00364
00365 frame_buffer[j++] = 1;
00366 frame_buffer[j++] = 0;
00367 frame_buffer[j++] = 0;
00368 frame_buffer[j++] = 0;
00369
00370 frame_buffer[j++] = 1;
00371 frame_buffer[j++] = 0;
00372
00373 frame_buffer[j++] = 0;
00374 frame_buffer[j++] = 0;
00375 frame_buffer[j++] = 0;
00376 frame_buffer[j++] = 0;
00377 frame_buffer[j++] = 0;
00378 frame_buffer[j++] = 0;
00379 frame_buffer[j++] = 0;
00380 frame_buffer[j++] = 0;
00381 frame_buffer[j++] = 0;
00382 frame_buffer[j++] = 0;
00383
00384
00385 data1 = data + 1;
00386
00387 while(i < size)
00388 {
00389 frame_buffer[j++] = data[i++];
00390 }
00391
00392
00393 if(!even_field_first)
00394 {
00395 for(i = 0; i < frame1size; )
00396 {
00397 frame_buffer[j++] = data[i++];
00398 }
00399 }
00400
00401 real_size = j;
00402
00403 frame_buffer[size_qword++] = (real_size & 0xff);
00404 frame_buffer[size_qword++] = ((real_size & 0xff00) >> 8);
00405 frame_buffer[size_qword++] = ((real_size & 0xff0000) >> 16);
00406 frame_buffer[size_qword++] = ((real_size & 0xff000000) >> 24);
00407
00408
00409 result = !fwrite(frame_buffer,
00410 real_size,
00411 1,
00412 jvideo_fd);
00413 if(result) perror("VDeviceLML::write_buffer");
00414
00415 return result;
00416 }
00417
00418 ArrayList<int>* VDeviceLML::get_render_strategies()
00419 {
00420 return &render_strategies;
00421 }