00001 #include "asset.h"
00002 #include "bcsignals.h"
00003 #include "byteorder.h"
00004 #include "dv1394.h"
00005 #include "edit.h"
00006 #include "file.h"
00007 #include "filedv.h"
00008 #include "guicast.h"
00009 #include "interlacemodes.h"
00010 #include "language.h"
00011 #include "mutex.h"
00012 #include "mwindow.inc"
00013 #include "quicktime.h"
00014 #include "vframe.h"
00015 #include "videodevice.inc"
00016 #include "cmodel_permutation.h"
00017 #include "mainerror.h"
00018
00019
00020
00021 #include <sys/types.h>
00022 #include <sys/stat.h>
00023 #include <fcntl.h>
00024 #include <unistd.h>
00025 #include <string.h>
00026 #include <errno.h>
00027
00028 #include <iostream>
00029
00030 FileDV::FileDV(Asset *asset, File *file)
00031 : FileBase(asset, file)
00032 {
00033 stream = 0;
00034 decoder = 0;
00035 encoder = 0;
00036 audio_encoder = 0;
00037 audio_buffer = 0;
00038 video_buffer = 0;
00039 output_size = 0;
00040 video_position = 0;
00041 audio_position = 0;
00042
00043 audio_sample_buffer = 0;
00044 audio_sample_buffer_len = 0;
00045 audio_sample_buffer_start = 0;
00046 audio_sample_buffer_end = 0;
00047 audio_sample_buffer_maxsize = 0;
00048
00049 audio_frames_written = 0;
00050
00051 if(asset->format == FILE_UNKNOWN)
00052 asset->format = FILE_RAWDV;
00053 asset->byte_order = 0;
00054
00055 stream_lock = new Mutex("FileDV::stream_lock");
00056 decoder_lock = new Mutex("FileDV::decoder_lock");
00057 video_position_lock = new Mutex("FileDV::video_position_lock");
00058 }
00059
00060 FileDV::~FileDV()
00061 {
00062 if(stream) close_file();
00063
00064 if(decoder) dv_decoder_free(decoder);
00065 if(encoder) dv_encoder_free(encoder);
00066 if(audio_encoder) dv_encoder_free(audio_encoder);
00067
00068 delete stream_lock;
00069 delete decoder_lock;
00070 delete video_position_lock;
00071
00072 delete[] video_buffer;
00073 delete[] audio_buffer;
00074
00075 if(audio_sample_buffer)
00076 {
00077 for(int i = 0; i < asset->channels; i++)
00078 delete[] audio_sample_buffer[i];
00079 delete[] audio_sample_buffer;
00080 }
00081 }
00082
00083 void FileDV::get_parameters(BC_WindowBase *parent_window,
00084 Asset *asset,
00085 BC_WindowBase* &format_window,
00086 int audio_options,
00087 int video_options)
00088 {
00089 if(audio_options)
00090 {
00091 DVConfigAudio *window = new DVConfigAudio(parent_window, asset);
00092 format_window = window;
00093 window->create_objects();
00094 window->run_window();
00095 delete window;
00096 }
00097 else
00098 if(video_options)
00099 {
00100 DVConfigVideo *window = new DVConfigVideo(parent_window, asset);
00101 format_window = window;
00102 window->create_objects();
00103 window->run_window();
00104 delete window;
00105 }
00106
00107 }
00108
00109 int FileDV::reset_parameters_derived()
00110 {
00111 if(decoder) dv_decoder_free(decoder);
00112 if(encoder) dv_encoder_free(encoder);
00113 if(audio_encoder) dv_encoder_free(audio_encoder);
00114 decoder = 0;
00115 encoder = 0;
00116 audio_encoder = 0;
00117
00118 TRACE("FileDV::reset_parameters_derived 10")
00119
00120 TRACE("FileDV::reset_parameters_derived: 20")
00121 delete[] audio_buffer;
00122 delete[] video_buffer;
00123 TRACE("FileDV::reset_parameters_derived: 30")
00124
00125 audio_buffer = 0;
00126 video_buffer = 0;
00127
00128 if(stream) fclose(stream);
00129
00130 stream = 0;
00131
00132 audio_position = 0;
00133 video_position = 0;
00134
00135 if(audio_sample_buffer)
00136 {
00137 for(int i = 0; i < asset->channels; i++)
00138 delete[] audio_sample_buffer[i];
00139 delete[] audio_sample_buffer;
00140 }
00141 audio_sample_buffer = 0;
00142 audio_sample_buffer_start = 0;
00143 audio_sample_buffer_len = 0;
00144 audio_sample_buffer_end = 0;
00145 audio_sample_buffer_maxsize = 0;
00146
00147 audio_frames_written = 0;
00148
00149
00150 output_size = 0;
00151
00152 UNTRACE
00153 return 0;
00154 }
00155
00156 int FileDV::open_file(int rd, int wr)
00157 {
00158
00159 TRACE("FileDV::open_file 10")
00160
00161 if(wr)
00162 {
00163
00164 TRACE("FileDV::open_file 20")
00165
00166
00167 if (!(asset->height == 576 && asset->width == 720 && asset->frame_rate == 25) &&
00168 !(asset->height == 480 && asset->width == 720 && (asset->frame_rate >= 29.96 && asset->frame_rate <= 29.98)))
00169 {
00170 eprintf("Raw DV format does not support following resolution: %ix%i framerate: %f\nAllowed resolutions are 720x576 25fps (PAL) and 720x480 29.97fps (NTSC)\n", asset->width, asset->height, asset->frame_rate);
00171 if (asset->height == 480 && asset->width == 720 && asset->frame_rate == 30)
00172 {
00173 eprintf("Suggestion: Proper frame rate for NTSC DV is 29.97 fps, not 30 fps\n");
00174 }
00175 return 1;
00176 }
00177 if (!(asset->channels == 2 && (asset->sample_rate == 48000 || asset->sample_rate == 44100)) &&
00178 !((asset->channels == 4 || asset->channels == 2) && asset->sample_rate == 32000))
00179 {
00180 eprintf("Raw DV format does not support following audio configuration : %i channels at sample rate: %iHz\n", asset->channels, asset->sample_rate);
00181 return 1;
00182 }
00183
00184
00185 if((stream = fopen(asset->path, "w+b")) == 0)
00186 {
00187 eprintf("Error while opening \"%s\" for writing. \n%m\n", asset->path);
00188 return 1;
00189 }
00190
00191
00192 if(encoder) dv_encoder_free(encoder);
00193 encoder = dv_encoder_new(0,0,0);
00194 encoder->vlc_encode_passes = 3;
00195 encoder->static_qno = 0;
00196 encoder->force_dct = DV_DCT_AUTO;
00197
00198 if(audio_encoder) dv_encoder_free(audio_encoder);
00199 audio_encoder = dv_encoder_new(0, 0, 0);
00200 audio_encoder->vlc_encode_passes = 3;
00201 audio_encoder->static_qno = 0;
00202 audio_encoder->force_dct = DV_DCT_AUTO;
00203
00204 if(decoder) dv_decoder_free(decoder);
00205 decoder = dv_decoder_new(0,0,0);
00206 decoder->quality = DV_QUALITY_BEST;
00207
00208
00209 isPAL = (asset->height == 576 ? 1 : 0);
00210 encoder->isPAL = isPAL;
00211 output_size = (isPAL ? DV1394_PAL_FRAME_SIZE : DV1394_NTSC_FRAME_SIZE);
00212
00213
00214
00215 encoder->is16x9 = asset->aspect_ratio > 16 / 8;
00216 }
00217 else
00218 {
00219 unsigned char *temp;
00220
00221 TRACE("FileDV::open_file 30")
00222
00223 struct stat info;
00224
00225 TRACE("FileDV::open_file 40")
00226
00227 if((stream = fopen(asset->path, "rb")) == 0)
00228 {
00229 eprintf("Error while opening \"%s\" for reading. \n%m\n", asset->path);
00230 return 1;
00231 }
00232
00233
00234 temp = new unsigned char[DV1394_PAL_FRAME_SIZE];
00235 memset(temp, 0, DV1394_PAL_FRAME_SIZE);
00236
00237
00238 stat(asset->path, &info);
00239
00240 TRACE("FileDV::open_file 50")
00241
00242
00243
00244
00245
00246 fread(temp, DV1394_PAL_FRAME_SIZE, 1, stream);
00247
00248 TRACE("FileDV::open_file 60")
00249
00250 if(decoder) dv_decoder_free(decoder);
00251 decoder = dv_decoder_new(0,0,0);
00252 decoder->quality = DV_QUALITY_BEST;
00253
00254
00255 if(dv_parse_header(decoder, temp) > -1 )
00256 {
00257
00258
00259 asset->video_data = 1;
00260 asset->layers = 1;
00261
00262
00263
00264
00265
00266 if(dv_format_normal(decoder) != 0) asset->aspect_ratio = (double) 4 / 3;
00267 else asset->aspect_ratio = (double) 16 / 9;
00268
00269 asset->width = decoder->width;
00270 asset->height = decoder->height;
00271
00272 if(dv_is_progressive(decoder) > 0)
00273 asset->interlace_mode = BC_ILACE_MODE_NOTINTERLACED;
00274 else
00275 asset->interlace_mode = BC_ILACE_MODE_BOTTOM_FIRST;
00276
00277 isPAL = dv_is_PAL(decoder);
00278
00279 output_size = (isPAL ? DV1394_PAL_FRAME_SIZE : DV1394_NTSC_FRAME_SIZE);
00280 asset->video_length = info.st_size / output_size;
00281
00282 if(!asset->frame_rate)
00283 asset->frame_rate = (isPAL ? 25 : 29.97);
00284 strncpy(asset->vcodec, "dvc ", 4);
00285
00286
00287 asset->channels = dv_get_num_channels(decoder);
00288 if(asset->channels > 0)
00289 {
00290 asset->audio_data = 1;
00291 asset->sample_rate = dv_get_frequency(decoder);
00292
00293 asset->bits = 16;
00294 asset->audio_length = (int64_t) (info.st_size / output_size / asset->frame_rate * asset->sample_rate);
00295 strncpy(asset->acodec, "dvc ", 4);
00296 }
00297 else
00298 asset->audio_data = 0;
00299 }
00300 else
00301 {
00302 asset->audio_data = 0;
00303 asset->video_data = 0;
00304 }
00305
00306 fseeko(stream, 0, SEEK_SET);
00307 TRACE("FileDV::open_file 80")
00308
00309 delete[] temp;
00310 }
00311
00312
00313 video_buffer = new unsigned char[output_size + 4];
00314 audio_buffer = new unsigned char[output_size + 4];
00315
00316 UNTRACE
00317 return 0;
00318 }
00319
00320 int FileDV::check_sig(Asset *asset)
00321 {
00322 unsigned char temp[3];
00323 FILE *t_stream = fopen(asset->path, "rb");
00324
00325 fread(&temp, 3, 1, t_stream);
00326
00327 fclose(t_stream);
00328
00329 if(temp[0] == 0x1f &&
00330 temp[1] == 0x07 &&
00331 temp[2] == 0x00)
00332 return 1;
00333
00334 return 0;
00335 }
00336
00337 int FileDV::close_file_derived()
00338 {
00339 if(stream) fclose(stream);
00340 stream = 0;
00341
00342 return 0;
00343 }
00344
00345 int64_t FileDV::get_video_position()
00346 {
00347 return video_position;
00348 }
00349
00350 int64_t FileDV::get_audio_position()
00351 {
00352 return audio_position;
00353 }
00354
00355 int FileDV::set_video_position(int64_t x)
00356 {
00357 video_position = x;
00358 return 0;
00359 }
00360
00361 int FileDV::set_audio_position(int64_t x)
00362 {
00363 audio_position = x;
00364 return 0;
00365 }
00366
00367 int FileDV::audio_samples_copy(double **buffer, int64_t len)
00368 {
00369
00370 if(!audio_sample_buffer)
00371 {
00372 audio_sample_buffer = new int16_t*[asset->channels];
00373 if(!audio_sample_buffer)
00374 {
00375 fprintf(stderr, "ERROR: Unable to allocate memory for audio_sample_buffer.\n");
00376 return 1;
00377 }
00378
00379 for(int i = 0; i < asset->channels; i++)
00380 {
00381 audio_sample_buffer[i] = new int16_t[len * 2];
00382
00383 if(!audio_sample_buffer[i])
00384 {
00385 fprintf(stderr, "ERROR: Unable to allocate memory for "
00386 "audio_sample_buffer channel %d\n", i);
00387 return 1;
00388 }
00389 }
00390 audio_sample_buffer_maxsize = len * 2;
00391 audio_sample_buffer_len = 0;
00392 audio_sample_buffer_start = 0;
00393 audio_sample_buffer_end = 0;
00394 }
00395
00396 if(audio_sample_buffer_maxsize <= audio_sample_buffer_len + len)
00397 {
00398
00399 for(int i = 0; i < asset->channels; i++)
00400 {
00401 int16_t *tmp = new int16_t[(audio_sample_buffer_len + len) * 2];
00402 if(!tmp)
00403 {
00404 fprintf(stderr, "ERROR: Unable to reallocate memory for "
00405 "audio_sample_buffer channel %d\n", i);
00406 return 1;
00407 }
00408
00409 for(int a = 0, b = audio_sample_buffer_start;
00410 a < audio_sample_buffer_len;
00411 a++, b = (b < (audio_sample_buffer_maxsize - 1) ? (b + 1) : 0))
00412 {
00413 tmp[a] = audio_sample_buffer[i][b];
00414 }
00415
00416 delete[] audio_sample_buffer[i];
00417 audio_sample_buffer[i] = tmp;
00418 }
00419 audio_sample_buffer_start = 0;
00420 audio_sample_buffer_end = audio_sample_buffer_len - 1;
00421 audio_sample_buffer_maxsize = (audio_sample_buffer_len + len) * 2;
00422 }
00423
00424
00425 for(int i = 0; i < asset->channels; i++)
00426 {
00427 if(len + audio_sample_buffer_end < audio_sample_buffer_maxsize)
00428 {
00429
00430 for(int a = 0; a < len; a++)
00431 {
00432 audio_sample_buffer[i][audio_sample_buffer_end + a] =
00433 (buffer[i][a] * 32767);
00434 }
00435 if(i == (asset->channels - 1))
00436 audio_sample_buffer_end += len;
00437 }
00438 else
00439 {
00440
00441 int copy_size = audio_sample_buffer_maxsize - audio_sample_buffer_end;
00442
00443 for(int a = 0; a < copy_size; a++)
00444 audio_sample_buffer[i][a + audio_sample_buffer_end] =
00445 (buffer[i][a] * 32767);
00446
00447 for(int a = 0; a < len - copy_size; a++)
00448 audio_sample_buffer[i][a] = (buffer[i][a + copy_size] * 32767);
00449
00450 if(i == (asset->channels - 1))
00451 audio_sample_buffer_end = len - copy_size;
00452 }
00453 }
00454
00455 audio_sample_buffer_len += len;
00456
00457 return 0;
00458 }
00459
00460 int FileDV::write_samples(double **buffer, int64_t len)
00461 {
00462 if(audio_samples_copy(buffer, len) != 0)
00463 {
00464 eprintf("Unable to store sample");
00465 return 1;
00466 }
00467 video_position_lock->lock("FileDV::write_samples");
00468
00469 TRACE("FileDV::write_samples 200")
00470
00471
00472
00473 int nFrames = MIN(video_position - audio_frames_written,
00474 audio_sample_buffer_len * asset->frame_rate / asset->sample_rate);
00475
00476 video_position_lock->unlock();
00477
00478 TRACE("FileDV::write_samples 210")
00479
00480 int16_t **tmp_buf = new int16_t*[asset->channels];
00481 for(int a = 0; a < asset->channels; a++)
00482 tmp_buf[a] = new int16_t[asset->sample_rate];
00483
00484 TRACE("FileDV::write_samples 220")
00485
00486 for(int i = 0; i < nFrames; i++)
00487 {
00488 stream_lock->lock("FileDV::write_samples 10");
00489 if(fseeko(stream, (off_t) audio_frames_written * output_size, SEEK_SET) != 0)
00490 {
00491 eprintf("Unable to set audio write position to %lli\n", (off_t) audio_frames_written * output_size);
00492
00493 stream_lock->unlock();
00494 return 1;
00495 }
00496
00497 if(fread(audio_buffer, output_size, 1, stream) != 1)
00498 {
00499 eprintf("Unable to read from audio buffer file\n");
00500 stream_lock->unlock();
00501 return 1;
00502 }
00503
00504 stream_lock->unlock();
00505
00506
00507
00508 TRACE("FileDV::write_samples 230")
00509
00510 int samples = dv_calculate_samples(audio_encoder, asset->sample_rate,
00511 audio_frames_written);
00512
00513 if(samples > audio_sample_buffer_maxsize - 1 - audio_sample_buffer_start)
00514 {
00515 TRACE("FileDV::write_samples 240")
00516 int copy_size = audio_sample_buffer_maxsize - audio_sample_buffer_start - 1;
00517
00518 for(int a = 0; a < asset->channels; a++)
00519 {
00520 memcpy(tmp_buf[a], audio_sample_buffer[a] + audio_sample_buffer_start,
00521 copy_size * sizeof(int16_t));
00522 memcpy(tmp_buf[a] + copy_size, audio_sample_buffer[a],
00523 (samples - copy_size) * sizeof(int16_t));
00524 }
00525 TRACE("FileDV::write_samples 250")
00526
00527 if(dv_encode_full_audio(audio_encoder, tmp_buf, asset->channels,
00528 asset->sample_rate, audio_buffer) < 0)
00529 {
00530 eprintf("ERROR: unable to encode audio frame %d\n", audio_frames_written);
00531 }
00532 }
00533 else
00534 {
00535 TRACE("FileDV::write_samples 260")
00536 int16_t **tmp_buf2 = new int16_t*[asset->channels];
00537 for(int a = 0; a < asset->channels; a++)
00538 tmp_buf2[a] = audio_sample_buffer[a] + audio_sample_buffer_start;
00539 if(dv_encode_full_audio(audio_encoder, tmp_buf2,
00540 asset->channels, asset->sample_rate, audio_buffer) < 0)
00541 {
00542 eprintf("ERROR: unable to encode audio frame %d\n", audio_frames_written);
00543
00544 }
00545 delete[] tmp_buf2;
00546 }
00547
00548 TRACE("FileDV::write_samples 270")
00549
00550 stream_lock->lock("FileDV::write_samples 20");
00551 if(fseeko(stream, (off_t) audio_frames_written * output_size, SEEK_SET) != 0)
00552 {
00553 eprintf("ERROR: Unable to relocate for audio write to %lli\n", (off_t) audio_frames_written * output_size);
00554 stream_lock->unlock();
00555 return 1;
00556 }
00557
00558 if(fwrite(audio_buffer, output_size, 1, stream) != 1)
00559 {
00560 eprintf("Unable to write audio to audio buffer\n");
00561 stream_lock->unlock();
00562 return 1;
00563 }
00564
00565 stream_lock->unlock();
00566
00567 audio_frames_written++;
00568 audio_sample_buffer_len -= samples;
00569 audio_sample_buffer_start += samples;
00570 if(audio_sample_buffer_start >= audio_sample_buffer_maxsize)
00571 audio_sample_buffer_start -= audio_sample_buffer_maxsize;
00572 }
00573
00574 TRACE("FileDV::write_samples 280")
00575
00576 for(int a = 0; a < asset->channels; a++)
00577 delete[] tmp_buf[a];
00578 delete[] tmp_buf;
00579
00580 TRACE("FileDV::write_samples 290")
00581
00582
00583 UNTRACE
00584
00585 return 0;
00586 }
00587
00588 int FileDV::write_frames(VFrame ***frames, int len)
00589 {
00590 int result = 0;
00591
00592 if(stream == 0) return 1;
00593
00594 for(int j = 0; j < len && !result; j++)
00595 {
00596 VFrame *temp_frame = frames[0][j];
00597
00598
00599 switch(temp_frame->get_color_model())
00600 {
00601 case BC_COMPRESSED:
00602 memcpy(video_buffer, temp_frame->get_data(), output_size);
00603 break;
00604 case BC_YUV422:
00605
00606 dv_encode_full_frame(encoder, temp_frame->get_rows(),
00607 e_dv_color_yuv, video_buffer);
00608 break;
00609 case BC_RGB888:
00610
00611 dv_encode_full_frame(encoder, temp_frame->get_rows(),
00612 e_dv_color_rgb, video_buffer);
00613 break;
00614 default:
00615 unsigned char *data = new unsigned char[asset->height * asset->width * 2];
00616 unsigned char **cmodel_buf = new unsigned char *[asset->height];
00617
00618 unsigned char **row_pointers = temp_frame->get_rows();
00619 for(int i = 0; i < asset->height; i++)
00620 cmodel_buf[i] = data + asset->width * 2 * i;
00621
00622 cmodel_transfer(cmodel_buf,
00623 row_pointers,
00624 cmodel_buf[0],
00625 cmodel_buf[1],
00626 cmodel_buf[2],
00627 row_pointers[0],
00628 row_pointers[1],
00629 row_pointers[2],
00630 0,
00631 0,
00632 asset->width,
00633 asset->height,
00634 0,
00635 0,
00636 asset->width,
00637 asset->height,
00638 temp_frame->get_color_model(),
00639 BC_YUV422,
00640 0,
00641 asset->width,
00642 asset->width);
00643
00644 dv_encode_full_frame(encoder, cmodel_buf,
00645 e_dv_color_yuv, video_buffer);
00646
00647 delete[] cmodel_buf;
00648 delete[] data;
00649 break;
00650 }
00651
00652
00653
00654
00655 stream_lock->lock("FileDV::write_frames");
00656 if(fseeko(stream, (off_t) video_position * output_size, SEEK_SET) != 0)
00657 {
00658 eprintf("Unable to seek file to %lli\n", (off_t)(video_position * output_size));
00659 }
00660 if(fwrite(video_buffer, output_size, 1, stream) < 1)
00661 {
00662 eprintf("Unable to write video data to video buffer");
00663 }
00664 stream_lock->unlock();
00665
00666 video_position_lock->lock();
00667 video_position++;
00668 video_position_lock->unlock();
00669 }
00670
00671 return 0;
00672 }
00673
00674 int FileDV::read_compressed_frame(VFrame *buffer)
00675 {
00676 int64_t result;
00677 if(stream == 0) return 0;
00678
00679 if (fseeko(stream, (off_t) video_position * output_size, SEEK_SET))
00680 {
00681 eprintf("Unable to seek file to %lli\n", (off_t)(video_position * output_size));
00682 }
00683 result = fread(buffer->get_data(), output_size, 1, stream);
00684 video_position++;
00685
00686 buffer->set_compressed_size(result);
00687
00688 return result != 0;
00689 }
00690
00691 int FileDV::write_compressed_frame(VFrame *buffer)
00692 {
00693 int result = 0;
00694 if(stream == 0) return 0;
00695
00696 if (fseeko(stream, (off_t) video_position * output_size, SEEK_SET))
00697 {
00698 eprintf("Unable to seek file to %lli\n", (off_t)(video_position * output_size));
00699 }
00700 result = fwrite(buffer->get_data(), buffer->get_compressed_size(), 1, stream);
00701 video_position++;
00702 return result != 0;
00703 }
00704
00705 int64_t FileDV::compressed_frame_size()
00706 {
00707 return output_size;
00708 }
00709
00710 int FileDV::read_samples(double *buffer, int64_t len)
00711 {
00712 int count = 0;
00713 int result = 0;
00714 int frame_count = get_audio_frame(audio_position);
00715 int offset = get_audio_offset(audio_position);
00716
00717 stream_lock->lock("FileDV::read_samples");
00718 if(stream == 0)
00719 {
00720 stream_lock->unlock();
00721 return 1;
00722 }
00723 stream_lock->unlock();
00724
00725
00726
00727
00728
00729
00730 int channels = (asset->sample_rate == 32000 && decoder->audio->quantization == 12) ? 4 : 2;
00731
00732 int16_t **out_buffer = new int16_t*[channels];
00733 for(int i = 0; i < channels; i++)
00734 out_buffer[i] = new int16_t[DV_AUDIO_MAX_SAMPLES];
00735
00736 while(count < len)
00737 {
00738 stream_lock->lock();
00739
00740 if(fseeko(stream, (off_t) frame_count * output_size, SEEK_SET) != 0)
00741 {
00742 stream_lock->unlock();
00743 result = 1;
00744 break;
00745 }
00746
00747 if(fread(audio_buffer, output_size, 1, stream) < 1)
00748 {
00749 stream_lock->unlock();
00750 result = 1;
00751 break;
00752 }
00753
00754 stream_lock->unlock();
00755
00756 frame_count++;
00757
00758 decoder_lock->lock("FileDV::read_samples");
00759
00760 if(dv_decode_full_audio(decoder, audio_buffer, out_buffer) < 0)
00761 {
00762 eprintf("Error decoding audio frame %d\n", frame_count - 1);
00763 }
00764
00765 int end = dv_get_num_samples(decoder);
00766 decoder_lock->unlock();
00767
00768 if(len - count + offset < end)
00769 end = len - count + offset;
00770
00771 for(int i = offset; i < end; i++)
00772 buffer[count++] = out_buffer[file->current_channel][i] / 32767.0;
00773
00774 offset = 0;
00775 }
00776
00777 for(int i = 0; i < channels; i++)
00778 delete[] out_buffer[i];
00779 delete[] out_buffer;
00780
00781 audio_position += len;
00782
00783 return result;
00784 }
00785
00786 int FileDV::read_frame(VFrame *frame)
00787 {
00788 if(stream == 0) return 1;
00789 int pitches[3] = {720 * 2, 0, 0};
00790
00791 TRACE("FileDV::read_frame 1")
00792 unsigned char **row_pointers = frame->get_rows();
00793
00794
00795 TRACE("FileDV::read_frame 10")
00796
00797
00798 stream_lock->lock("FileDV::read_frame");
00799 if(fseeko(stream, (off_t) video_position * output_size, SEEK_SET) < 0)
00800 {
00801 eprintf("Unable to seek file to %lli", (off_t)(video_position * output_size));
00802 stream_lock->unlock();
00803 return 1;
00804 }
00805 fread(video_buffer, output_size, 1, stream);
00806 stream_lock->unlock();
00807 video_position++;
00808
00809
00810 TRACE("FileDV::read_frame 20")
00811
00812 switch(frame->get_color_model())
00813 {
00814 case BC_COMPRESSED:
00815
00816 TRACE("FileDV::read_frame 30")
00817
00818 frame->allocate_compressed_data(output_size);
00819 frame->set_compressed_size(output_size);
00820 memcpy(frame->get_data(), video_buffer, output_size);
00821 break;
00822 case BC_RGB888:
00823
00824 TRACE("FileDV::read_frame 40")
00825
00826 pitches[0] = 720 * 3;
00827 decoder_lock->lock("FileDV::read_frame 10");
00828 dv_decode_full_frame(decoder, video_buffer, e_dv_color_rgb,
00829 row_pointers, pitches);
00830 decoder_lock->unlock();
00831 break;
00832 case BC_YUV422:
00833 TRACE("FileDV::read_frame 50")
00834 decoder_lock->lock("FileDV::read_frame 20");
00835 dv_decode_full_frame(decoder, video_buffer, e_dv_color_yuv,
00836 row_pointers, pitches);
00837 decoder_lock->unlock();
00838 break;
00839
00840 default:
00841 unsigned char *data = new unsigned char[asset->height * asset->width * 2];
00842 unsigned char **temp_pointers = new unsigned char*[asset->height];
00843
00844 for(int i = 0; i < asset->height; i++)
00845 temp_pointers[i] = data + asset->width * 2 * i;
00846
00847
00848 TRACE("FileDV::read_frame 69")
00849
00850 decoder_lock->lock("FileDV::read_frame 30");
00851 dv_decode_full_frame(decoder, video_buffer, e_dv_color_yuv,
00852 temp_pointers, pitches);
00853 decoder_lock->unlock();
00854
00855 TRACE("FileDV::read_frame 70")
00856
00857 cmodel_transfer(row_pointers,
00858 temp_pointers,
00859 row_pointers[0],
00860 row_pointers[1],
00861 row_pointers[2],
00862 temp_pointers[0],
00863 temp_pointers[1],
00864 temp_pointers[2],
00865 0,
00866 0,
00867 asset->width,
00868 asset->height,
00869 0,
00870 0,
00871 asset->width,
00872 asset->height,
00873 BC_YUV422,
00874 frame->get_color_model(),
00875 0,
00876 asset->width,
00877 asset->width);
00878
00879
00880
00881 delete[] temp_pointers;
00882 delete[] data;
00883
00884
00885 break;
00886 }
00887
00888 TRACE("FileDV::read_frame 80")
00889
00890 UNTRACE
00891
00892 return 0;
00893 }
00894
00895 int FileDV::colormodel_supported(int colormodel)
00896 {
00897 return colormodel;
00898 }
00899
00900 int FileDV::can_copy_from(Edit *edit, int64_t position)
00901 {
00902 if(edit->asset->format == FILE_RAWDV ||
00903 (edit->asset->format == FILE_MOV &&
00904 (match4(edit->asset->vcodec, QUICKTIME_DV) ||
00905 match4(edit->asset->vcodec, QUICKTIME_DVSD) ||
00906 match4(edit->asset->vcodec, QUICKTIME_DVCP))))
00907 return 1;
00908
00909 return 0;
00910 }
00911
00912 int FileDV::get_best_colormodel(Asset *asset, int driver)
00913 {
00914 switch(driver)
00915 {
00916 case PLAYBACK_X11:
00917 return BC_RGB888;
00918 break;
00919 case PLAYBACK_X11_XV:
00920 return BC_YUV422;
00921 break;
00922 case PLAYBACK_DV1394:
00923 case PLAYBACK_FIREWIRE:
00924 return BC_COMPRESSED;
00925 break;
00926 case PLAYBACK_LML:
00927 case PLAYBACK_BUZ:
00928 return BC_YUV422P;
00929 break;
00930 case VIDEO4LINUX:
00931 case VIDEO4LINUX2:
00932 case CAPTURE_BUZ:
00933 case CAPTURE_LML:
00934 case VIDEO4LINUX2JPEG:
00935 return BC_YUV422;
00936 break;
00937 case CAPTURE_FIREWIRE:
00938 return BC_COMPRESSED;
00939 break;
00940 }
00941 return BC_RGB888;
00942 }
00943
00944 int FileDV::get_audio_frame(int64_t pos)
00945 {
00946 return (double) pos * asset->frame_rate / asset->sample_rate;
00947 }
00948
00949
00950 int FileDV::get_audio_offset(int64_t pos)
00951 {
00952 int frame = get_audio_frame(pos);
00953
00954
00955 return pos - frame * asset->sample_rate / asset->frame_rate;
00956 }
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978 DVConfigAudio::DVConfigAudio(BC_WindowBase *parent_window, Asset *asset)
00979 : BC_Window(PROGRAM_NAME ": Audio Compression",
00980 parent_window->get_abs_cursor_x(1),
00981 parent_window->get_abs_cursor_y(1),
00982 350,
00983 250)
00984 {
00985 this->parent_window = parent_window;
00986 this->asset = asset;
00987 }
00988
00989 DVConfigAudio::~DVConfigAudio()
00990 {
00991
00992 }
00993
00994 int DVConfigAudio::create_objects()
00995 {
00996 add_tool(new BC_Title(10, 10, _("There are no audio options for this format")));
00997 add_subwindow(new BC_OKButton(this));
00998 return 0;
00999 }
01000
01001 int DVConfigAudio::close_event()
01002 {
01003 set_done(0);
01004 return 1;
01005 }
01006
01007
01008
01009
01010
01011
01012 DVConfigVideo::DVConfigVideo(BC_WindowBase *parent_window, Asset *asset)
01013 : BC_Window(PROGRAM_NAME ": Video Compression",
01014 parent_window->get_abs_cursor_x(1),
01015 parent_window->get_abs_cursor_y(1),
01016 350,
01017 250)
01018 {
01019 this->parent_window = parent_window;
01020 this->asset = asset;
01021 }
01022
01023 DVConfigVideo::~DVConfigVideo()
01024 {
01025
01026 }
01027
01028 int DVConfigVideo::create_objects()
01029 {
01030 add_tool(new BC_Title(10, 10, _("There are no video options for this format")));
01031 add_subwindow(new BC_OKButton(this));
01032 return 0;
01033 }
01034
01035 int DVConfigVideo::close_event()
01036 {
01037 set_done(0);
01038 return 1;
01039 }