r602: Fix baver's code... don't insert timecode when show_tc is not set
[cinelerra_cv/mob.git] / cinelerra / filedv.C
blobe94a967c8efc80cfc226b6e6bb2f50f0ef6c1588
1 #ifdef HAVE_FIREWIRE
3 #include "asset.h"
4 #include "bcsignals.h"
5 #include "byteorder.h"
6 #include "dv1394.h"
7 #include "edit.h"
8 #include "file.h"
9 #include "filedv.h"
10 #include "guicast.h"
11 #include "interlacemodes.h"
12 #include "language.h"
13 #include "mwindow.inc"
14 #include "quicktime.h"
15 #include "vframe.h"
16 #include "videodevice.inc"
17 #include "cmodel_permutation.h"
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <fcntl.h>
22 #include <unistd.h>
23 #include <string.h>
24 #include <errno.h>
26 FileDV::FileDV(Asset *asset, File *file)
27  : FileBase(asset, file)
29 #ifdef DV_USE_FFMPEG
30         avcodec_init();
31         avcodec_register_all();
32         codec = 0;
33         context = 0;
34         picture = 0;
35 #endif // DV_USE_FFMPEG
37         decoder = 0;
38         encoder = 0;
39         audio_buffer = 0;
40         input = 0;
41         output = 0;
42         if(asset->format == FILE_UNKNOWN)
43                 asset->format = FILE_RAWDV;
44         asset->byte_order = 0;
45         isPAL = 0;
46         reset_parameters();
49 FileDV::~FileDV()
51         int i = 0;
52         if(stream) close_file();
54 #ifdef DV_USE_FFMPEG
55         if(context)
56         {
57                 avcodec_close(context);
58                 free(context);
59         }
60         if(picture) free(picture);
61 #endif // DV_USE_FFMPEG
63         if(decoder) dv_decoder_free(decoder);
64         if(encoder) dv_encoder_free(encoder);
65         if(audio_buffer)
66         {
67                 for(i = 0; i < asset->channels; i++)
68                         free(audio_buffer[i]);
69                 free(audio_buffer);
70         }
71         delete[] output;
72         delete[] input;
75 void FileDV::get_parameters(BC_WindowBase *parent_window,
76         Asset *asset,
77         BC_WindowBase* &format_window,
78         int audio_options,
79         int video_options)
81         if(audio_options)
82         {
83                 DVConfigAudio *window = new DVConfigAudio(parent_window, asset);
84                 format_window = window;
85                 window->create_objects();
86                 window->run_window();
87                 delete window;
88         }
89         else
90         if(video_options)
91         {
92                 DVConfigVideo *window = new DVConfigVideo(parent_window, asset);
93                 format_window = window;
94                 window->create_objects();
95                 window->run_window();
96                 delete window;
97         }
101 int FileDV::reset_parameters_derived()
103         int i = 0;
105 #ifdef DV_USE_FFMPEG
106         if(codec)
107         {
108                 avcodec_close(context);
109                 free(context);
110                 context = 0;
111                 codec = 0;
112         }
113         if(picture) free(picture);
114         picture = 0;
115 #endif // DV_USE_FFMPEG
117         if(decoder) dv_decoder_free(decoder);
118         if(encoder) dv_encoder_free(encoder);
120 TRACE("FileDV::reset_parameters_derived 10")
122 #ifdef DV_USE_FFMPEG
123         codec = avcodec_find_decoder(CODEC_ID_DVVIDEO);
124         context = avcodec_alloc_context();
125         avcodec_open(context, codec);
126 #endif // DV_USE_FFMPEG
128         decoder = dv_decoder_new(0,0,0);
129         decoder->quality = DV_QUALITY_BEST;
130         encoder = dv_encoder_new(0,0,0);
131         encoder->vlc_encode_passes = 3;
132         encoder->static_qno = 0;
133         encoder->force_dct = DV_DCT_AUTO;
134         
135 TRACE("FileDV::reset_parameters_derived: 20")
136         
137         if(audio_buffer)
138         {
139                 for(i = 0; i < asset->channels; i++)
140                 {
141                         if(audio_buffer[i]) free(audio_buffer[i]);
142                 }
143                 free(audio_buffer);
144         }
146 TRACE("FileDV::reset_parameters_derived: 30")
147         
148         audio_buffer = 0;
149         samples_in_buffer = 0;
150         for(i = 0; i < 4; i++) // max 4 channels in dv
151                 samples_offset[i] = 0;
153         frames_written = 0;
155         stream = 0;
156         audio_position = 0;
157         video_position = 0;
158 // output_size gets set in open_file, once we know if the frames are PAL or NTSC
159 // output and input are allocated at the same point.
160         output_size = 0;
161         delete[] output;
162         delete[] input;
163         audio_offset = 0;
164         video_offset = 0;
165         current_frame = asset->tcstart;
166         
167 UNTRACE
171 int FileDV::open_file(int rd, int wr)
174 TRACE("FileDV::open_file 10")
176         if(wr)
177         {
179 TRACE("FileDV::open_file 20")
181                 if((stream = fopen(asset->path, "w+b")) == 0)
182                 {
183                         perror(_("FileDV::open_file rdwr"));
184                         return 1;
185                 }
187                 isPAL = (asset->height == 576 ? 1 : 0);
188                 encoder->isPAL = isPAL;
189                 output_size = (isPAL ? DV1394_PAL_FRAME_SIZE : DV1394_NTSC_FRAME_SIZE);
190         }
191         else
192         {
193                 unsigned char *temp;
195 TRACE("FileDV::open_file 30")
197                 struct stat *info;
199 TRACE("FileDV::open_file 40")
201                 if((stream = fopen(asset->path, "rb")) == 0)
202                 {
203                         perror(_("FileDV::open_file rd"));
204                         return 1;
205                 }
207                 // temp storage to find out the correct info from the stream.
208                 temp = new unsigned char[DV1394_PAL_FRAME_SIZE + 8];
209                 memset(temp, 0, DV1394_PAL_FRAME_SIZE + 8);
211                 // need file size info to get length.
212                 info = (struct stat*) malloc(sizeof(struct stat));
213                 stat(asset->path, info);
214                 
215 TRACE("FileDV::open_file 50")
217                 // read the first frame so we can get the stream info from it
218                 // by reading the greatest possible frame size, we ensure we get all the
219                 // data. libdv will determine if it's PAL or NTSC, and input and output
220                 // buffers get allocated accordingly.
221                 fread(temp, DV1394_PAL_FRAME_SIZE, 1, stream);
223 TRACE("FileDV::open_file 60")
225                 if(dv_parse_header(decoder, temp) > -1 )
226                 {
227                         char tc[12];
228                         
229                         // define video params first -- we need to find out output_size
230                         // always have video
231                         asset->video_data = 1;
232                         asset->layers = 1;
233                         asset->aspect_ratio = (double) 4 / 3;
234                         asset->width = decoder->width;
235                         asset->height = decoder->height;
236                         asset->interlace_mode = BC_ILACE_MODE_UNDETECTED; // FIXME: Is this set to a standard??
237                         if(asset->height == 576)
238                         {
239                                 isPAL = 1;
240                                 encoder->isPAL = 1;
241                         }
242                         output_size = (isPAL ? DV1394_PAL_FRAME_SIZE : DV1394_NTSC_FRAME_SIZE);
243                         asset->video_length = info->st_size / output_size;
244                         if(!asset->frame_rate)
245                                 asset->frame_rate = (isPAL ? 25 : 29.97);
246                         strncpy(asset->vcodec, "dvc ", 4);
248                         // see if there are any audio tracks
249                         asset->channels = decoder->audio->num_channels;
250                         if(asset->channels > 0)
251                         {
252                                 asset->audio_data = 1;
253                                 asset->sample_rate = decoder->audio->frequency;
254                                 asset->bits = decoder->audio->quantization;
255                                 asset->audio_length = info->st_size * decoder->audio->samples_this_frame / output_size;
256                                 strncpy(asset->acodec, "dvc ", 4);
257                         }
258                         else
259                                 asset->audio_data = 0;
261                         // Set start timecode
262                         dv_parse_packs(decoder, temp);
263                         dv_get_timestamp(decoder, tc);
264                         asset->set_timecode(tc, TC_DROPFRAME, 0);
266                         // Get the last frame's timecode
267                         set_video_position(asset->video_length);
268                         fread(temp, DV1394_PAL_FRAME_SIZE, 1, stream);
269                         dv_parse_header(decoder, temp);
270                         dv_parse_packs(decoder, temp);
271                         dv_get_timestamp(decoder, tc);
272                         
273                         asset->set_timecode(tc, TC_DROPFRAME, 1);
274                 }
275                 else
276                 {
277                         asset->audio_data = 0;
278                         asset->video_data = 0;
279                 }
281                 fseek(stream, 0, SEEK_SET);
282 TRACE("FileDV::open_file 80")
284                 delete[] temp;
285                 free(info);
286         }
287         delete[] input;
288         delete[] output;
290         /// allocate space for input and output
291         input = new unsigned char[output_size + 8];
292         output = new unsigned char[output_size + 8];
293         memset(input, 0, output_size + 8);
294         memset(output, 0, output_size + 8);
295                         
296 UNTRACE
297         return 0;
300 int FileDV::check_sig(Asset *asset)
302         unsigned char temp[3];
303         FILE *t_stream = fopen(asset->path, "rb");
305         fread(&temp, 3, 1, t_stream);
307         fclose(t_stream);
308         
309         if(temp[0] == 0x1f &&
310                         temp[1] == 0x07 &&
311                         temp[2] == 0x00)
312                 return 1;
314         return 0;
317 int FileDV::close_file()
319         fclose(stream);
320         stream = 0;
323 int FileDV::close_file_derived()
325 //printf("FileDV::close_file_derived(): 1\n");
326         fclose(stream);
327         stream = 0;
330 int64_t FileDV::get_video_position()
332         return video_offset / output_size;
335 int64_t FileDV::get_audio_position()
337         return audio_position;
340 int FileDV::set_video_position(int64_t x)
342         if(!stream) return 1;
343         if(x >= 0 && x < asset->video_length)
344         {
345                 video_offset = x * output_size;
346                 return 0;
347         }
348         else
349                 return 1;
352 int FileDV::set_audio_position(int64_t x)
354         int i = 0;
355         if(!stream) return 1;
356         if(x >= 0 && x < asset->audio_length)
357         {
358                 audio_position = x;
359                 audio_offset = output_size * (int64_t) (x / (asset->sample_rate / asset->frame_rate));
360                 for(i = 0; i < 4; i++)
361                 {
362                         samples_offset[i] = audio_position - (int) (audio_offset / output_size / asset->frame_rate * asset->sample_rate);
363                 }
364                 return 0;
365         }
366         else
367                 return 1;
370 int FileDV::write_samples(double **buffer, int64_t len)
372         int frame_num = (int) (audio_offset / output_size);
373         // How many samples do we write this frame?
374         int samples = calculate_samples(frame_num);
375         int samples_written = 0;
376         int i, j, k = 0;
377         unsigned char *temp_data = (unsigned char *) calloc(sizeof(unsigned char*), output_size);
378         int16_t *temp_buffers[asset->channels];
380 TRACE("FileDV::write_samples 10")
382         if(!audio_buffer)
383         {
384                 audio_buffer = (int16_t **) calloc(sizeof(int16_t*), asset->channels);
386                 // TODO: should reallocate if len > asset->sample_rate * 2, or
387                 // len > asset->sample_rate + samples_in_buffer
388                 
389                 // allocate enough so that we can write two seconds worth of frames (we
390                 // usually receive one second of frames to write, and we need
391                 // overflow if the frames aren't already written
392                 for(i = 0; i < asset->channels; i++)
393                 {
394                         audio_buffer[i] = (int16_t *) calloc(sizeof(int16_t), asset->sample_rate * 2);
395                 }
396         }
398 TRACE("FileDV::write_samples 20")
400         for(i = 0; i < asset->channels; i++)
401         {
402                 temp_buffers[i] = audio_buffer[i];
403                 // Need case handling for bitsize ?
405 TRACE("FileDV::write_samples 22")
407                 for(j = 0; j < len; j++)
408                 {
410 TRACE("FileDV::write_samples 24")
412                         if(samples_in_buffer > 0)
413                                 temp_buffers[i][j + samples_in_buffer - 1] = (int16_t) (buffer[i][j] * 32767);
414                         else
415                                 temp_buffers[i][j] = (int16_t) (buffer[i][j] * 32767);
416                 }
417         }
419         samples_in_buffer += len;
421 TRACE("FileDV::write_samples 30")
423 // We can only write the number of frames that write_frames has written
424 // since our last audio write, and we can't write more than the
425 // samples we have available from the last write and this one
426         for(i = 0; i < frames_written && samples_written + samples <= samples_in_buffer; i++)
427         {
428                 // Position ourselves to where we last wrote audio
429                 fseek(stream, audio_offset, SEEK_SET);
431                 // Read the frame in, add the audio, write it back out to the same
432                 // location and adjust audio_offset to the new file position
433                 if(fread(temp_data, output_size, 1, stream) < 1) break;
434                 encoder->samples_this_frame = samples;
435                 dv_encode_full_audio(encoder, temp_buffers, asset->channels,
436                         asset->sample_rate, temp_data);
437                 fseek(stream, audio_offset, SEEK_SET);
438                 fwrite(temp_data, output_size, 1, stream);
439                 audio_offset += output_size;
441 TRACE("FileDV::write_samples 50")
443                 // Get the next set of samples for the next frame
444                 for(j = 0; j < asset->channels; j++)
445                         temp_buffers[j] += samples;
447 TRACE("FileDV::write_samples 60")
449                 // increase the number of samples written so we can determine how many
450                 // samples to leave in the buffer for the next write
451                 samples_written += samples;
452                 frame_num++;
453                 samples = calculate_samples(frame_num);
454         }
456         // Get number of frames we didn't write to
457         frames_written -= i;
459         if(samples_written < samples_in_buffer)
460         {
461         // move the rest of the buffer to the front
463 TRACE("FileDV::write_samples 70")
465                 samples_in_buffer -= samples_written;
466                 for(i = 0; i < asset->channels; i++)
467                 {
468                         memmove(audio_buffer[i], temp_buffers[i], asset->sample_rate * 2 - samples_written);
469                 }
470         }
471         else
472         {
473                 samples_in_buffer = 0;
474         }
476 TRACE("FileDV::write_samples 80")
478         if(temp_data) free(temp_data);
480 UNTRACE
482         return 0;
485 int FileDV::write_frames(VFrame ***frames, int len)
487         int i, j, result = 0;
489         if(!stream) return 0;
491         for(j = 0; j < len && !result; j++)
492         {
493                 VFrame *temp_frame = new VFrame(frames[0][j]->get_data(),
494                         asset->width,
495                         asset->height,
496                         frames[0][j]->get_color_model(),
497                         frames[0][j]->get_bytes_per_line());
499                         unsigned char *frame_buf = (unsigned char *)malloc(asset->height * asset->width * 2);
500                         unsigned char **cmodel_buf = (unsigned char **)malloc(sizeof(unsigned char*) * asset->height);
502                         for(i = 0; i < asset->height; i++)
503                                 cmodel_buf[i] = frame_buf + 720 * 2 * i;
505 //printf("FileDV::write_frames: color_model %i\n", temp_frame->get_color_model());
506                         switch(temp_frame->get_color_model())
507                         {
508                                 case BC_COMPRESSED:
509                                         memcpy(output, temp_frame->get_data(), output_size);
510                                         break;
511                                 case BC_YUV422:
512 //printf("FileDV::write_frames: 4\n");
513                                         dv_encode_full_frame(encoder, temp_frame->get_rows(),
514                                                 e_dv_color_yuv, output);
515                                         break;
516                                 case BC_RGB888:
517 //printf("FileDV::write_frames: 5\n");
518                                         dv_encode_full_frame(encoder, temp_frame->get_rows(),
519                                                 e_dv_color_rgb, output);
520                                         break;
521                                 default:
522 //printf("FileDV::write_frames: 6\n");
523                                         unsigned char **row_pointers = temp_frame->get_rows();
524                                         cmodel_transfer(cmodel_buf,
525                                                 row_pointers,
526                                                 cmodel_buf[0],
527                                                 cmodel_buf[1],
528                                                 cmodel_buf[2],
529                                                 row_pointers[0],
530                                                 row_pointers[1],
531                                                 row_pointers[2],
532                                                 0,
533                                                 0,
534                                                 asset->width,
535                                                 asset->height,
536                                                 0,
537                                                 0,
538                                                 asset->width,
539                                                 asset->height,
540                                                 temp_frame->get_color_model(),
541                                                 BC_YUV422,
542                                                 0,
543                                                 asset->width,
544                                                 asset->width);
546                                         dv_encode_full_frame(encoder, cmodel_buf,
547                                                 e_dv_color_yuv, output);
548                                         break;
549                         }
550 //printf("FileDV::write_frames: 7\n");
552                 fseek(stream, video_offset, SEEK_SET);
553                 fwrite(output, output_size, 1, stream);
554                 video_offset += output_size;
555                 frames_written++;
557                 free(cmodel_buf);
558                 free(frame_buf);
559                 delete temp_frame;
560                 }
561                 
562         return 0;
565 int FileDV::read_compressed_frame(VFrame *buffer)
567         int64_t result;
568         if(!stream) return 0;
570         fseek(stream, video_offset, SEEK_SET);
571         fread(buffer->get_data(), output_size, 1, stream);
572         video_offset += output_size;
574         buffer->set_compressed_size(result);
575         result = !result;
576         
577         return result;
580 int FileDV::write_compressed_frame(VFrame *buffer)
582         int result = 0;
583         if(!stream) return 0;
585         fseek(stream, video_offset, SEEK_SET);
586         fwrite(buffer->get_data(), buffer->get_compressed_size(), 1, stream);
587         video_offset += output_size;
589         frames_written++;
591         return result;
594 int64_t FileDV::compressed_frame_size()
596         if(!stream) return 0;
597         return output_size;
600 int FileDV::read_samples(double *buffer, int64_t len)
602         int frameno = audio_offset / output_size;
603         int16_t **outbuf = 0;
604         int16_t **temp_buffer = 0;
605         int i, j = 0;
606         int channel = file->current_channel;
607         int offset = samples_offset[channel];
609 TRACE("FileDV::read_samples 10")
611         outbuf = (int16_t **) calloc(sizeof(int16_t *), asset->channels);
612         temp_buffer = (int16_t **) calloc(sizeof(int16_t *), asset->channels);
614 TRACE("FileDV::read_samples 20")
616         for(i = 0; i < asset->channels; i++)
617         {
618         // need a bit extra, since chances are len is not a multiple of the
619         // samples per frame.
621 TRACE("FileDV::read_samples 30")
623                 outbuf[i] = (int16_t *) calloc(sizeof(int16_t), len + 2 * DV_AUDIO_MAX_SAMPLES);
624                 temp_buffer[i] = outbuf[i];
625         }
627 TRACE("FileDV::read_samples 40")
629         // set file position
630         fseek(stream, audio_offset, SEEK_SET);
632         // get audio data and put it in buffer
633         for(i = 0; i < len + calculate_samples(frameno); i += calculate_samples(frameno))
634         {
636 TRACE("FileDV::read_samples 50")
638                 fread(input, output_size, 1, stream);
639                 audio_offset += output_size;
640                 dv_decode_full_audio(decoder, input, temp_buffer);
642 TRACE("FileDV::read_samples 60")
644                 for(j = 0; j < asset->channels; j++)
645                         temp_buffer[j] += calculate_samples(frameno);
647                 frameno++;
648         }
650 TRACE("FileDV::read_samples 70")
652         for(i = 0; i < len; i++)
653                 buffer[i] = (double) outbuf[channel][i + offset] / 32767;
655 TRACE("FileDV::read_samples 80")
657         samples_offset[channel] = (len + offset) % calculate_samples(frameno);
659 TRACE("FileDV::read_samples 90")
661 // we do this to keep everything in sync. When > 1 channel is being
662 // played, our set_audio_position gets overriden every second time,
663 // which is a Good Thing (tm) since it would otherwise be wrong.
664         set_audio_position(audio_position + len);
666 TRACE("FileDV::read_samples 100")
668         free(temp_buffer);
670 TRACE("FileDV::read_samples 105")
672         for(i = 0; i < asset->channels; i++)
673                 free(outbuf[i]);
675 TRACE("FileDV::read_samples 110")
677         free(outbuf);
679 UNTRACE
681         return 0;
684 int FileDV::read_frame(VFrame *frame)
686         if(!stream) return 1;
687         int i, result = 0;
688         int pitches[3] = {720 * 2, 0, 0};
690 TRACE("FileDV::read_frame 1")
692         unsigned char **row_pointers = frame->get_rows();
694         unsigned char *temp_data = (unsigned char *) malloc(asset->height * asset->width * 2);
695         unsigned char **temp_pointers = (unsigned char **)malloc(sizeof(unsigned char *) * asset->height);
697 TRACE("FileDV::read_frame 10")
699         for(i = 0; i < asset->height; i++)
700                 temp_pointers[i] = temp_data + asset->width * 2 * i;
702         // Seek to video position
703         if(fseek(stream, video_offset, SEEK_SET) < 0) return 1;
704         fread(input, output_size, 1, stream);
705         video_offset += output_size;
706         
708 TRACE("FileDV::read_frame 20")
710         switch(frame->get_color_model())
711         {
712                 case BC_COMPRESSED:
714 TRACE("FileDV::read_frame 30")
716                         frame->allocate_compressed_data(output_size);
717                         frame->set_compressed_size(output_size);
718                         memcpy(frame->get_data(), input, output_size);
719                         break;
720 #ifndef DV_USE_FFMPEG
722                 case BC_RGB888:
724 TRACE("FileDV::read_frame 40")
726                         pitches[0] = 720 * 3;
727                         dv_decode_full_frame(decoder, input, e_dv_color_rgb,
728                                 row_pointers, pitches);
729                         break;
730                 case BC_YUV422:
732 TRACE("FileDV::read_frame 50")
734                         dv_decode_full_frame(decoder, input, e_dv_color_yuv,
735                                 row_pointers, pitches);
736                         break;
738 #endif // DV_USE_FFMPEG
740                 default:
741                 
742 TRACE("FileDV::read_frame 60")
744 #ifdef DV_USE_FFMPEG
746                         int got_picture = 0;
747                         AVPicture temp_picture;
749 TRACE("FileDV::read_frame 61")
751                         temp_picture.linesize[0] = 720 * 2;
752                         for(i = 0; i < 4; i++)
753                                 temp_picture.data[i] = temp_pointers[i];
755 TRACE("FileDV::read_frame 62")
757                         if(!picture)
758                                 picture = avcodec_alloc_frame();
760 TRACE("FileDV::read_frame 63")
762                         avcodec_decode_video(context,
763                                 picture,
764                                 &got_picture,
765                                 input,
766                                 output_size);
768 TRACE("FileDV::read_frame 65")
770                         img_convert(&temp_picture,
771                                 PIX_FMT_YUV422,
772                                 (AVPicture *)picture,
773                                 (isPAL ? PIX_FMT_YUV420P : PIX_FMT_YUV411P),
774                                 asset->width,
775                                 asset->height);
777 #else
779 TRACE("FileDV::read_frame 69")
781                         dv_decode_full_frame(decoder, input, e_dv_color_yuv,
782                                 temp_pointers, pitches);
784 #endif // DV_USE_FFMPEG
786 TRACE("FileDV::read_frame 70")
788                         cmodel_transfer(row_pointers,
789                                 temp_pointers,
790                                 row_pointers[0],
791                                 row_pointers[1],
792                                 row_pointers[2],
793                                 temp_pointers[0],
794                                 temp_pointers[1],
795                                 temp_pointers[2],
796                                 0,
797                                 0,
798                                 asset->width,
799                                 asset->height,
800                                 0,
801                                 0,
802                                 asset->width,
803                                 asset->height,
804                                 BC_YUV422,
805                                 frame->get_color_model(),
806                                 0,
807                                 asset->width,
808                                 asset->width);
809                         break;
810         }
812 TRACE("FileDV::read_frame 80")
814         free(temp_pointers);
815         free(temp_data);
817 UNTRACE
819         return 0;       
822 int FileDV::colormodel_supported(int colormodel)
824         return colormodel;
827 int FileDV::can_copy_from(Edit *edit, int64_t position)
829         if(edit->asset->format == FILE_RAWDV ||
830                         (edit->asset->format == FILE_MOV &&
831                                 (match4(edit->asset->vcodec, QUICKTIME_DV) ||
832                                 match4(edit->asset->vcodec, QUICKTIME_DVSD))))
833                 return 1;
835         return 0;
838 int FileDV::get_best_colormodel(Asset *asset, int driver)
840         switch(driver)
841         {
842                 case PLAYBACK_X11:
843                         return BC_RGB888;
844                         break;
845                 case PLAYBACK_X11_XV:
846                         return BC_YUV422;
847                         break;
848                 case PLAYBACK_DV1394:
849                 case PLAYBACK_FIREWIRE:
850                         return BC_COMPRESSED;
851                         break;
852                 case PLAYBACK_LML:
853                 case PLAYBACK_BUZ:
854                         return BC_YUV422P;
855                         break;
856                 case VIDEO4LINUX:
857                 case VIDEO4LINUX2:
858                 case CAPTURE_BUZ:
859                 case CAPTURE_LML:
860                 case VIDEO4LINUX2JPEG:
861                         return BC_YUV422;
862                         break;
863                 case CAPTURE_FIREWIRE:
864                         return BC_COMPRESSED;
865                         break;
866         }
867         return BC_RGB888;
870 // from libdv's dv_calculate_samples, included here for use with ffmpeg and in
871 // case user's libdv doesn't support calculate_samples (although it should).
872 int FileDV::calculate_samples(int frame_count)
874         int samples = 0;
875         if(isPAL)
876         {
877                 samples = asset->sample_rate / 25;
878                 switch(asset->sample_rate)
879                 {
880                         case 48000:
881                                 if(frame_count % 25 == 0)
882                                         samples--;
883                                 break;
884                         case 44100:
885                         case 32000:
886                                 break;
887                         default:
888                                 samples = 0;
889                                 break;
890                 }
891         }
892         else
893         {
894                 samples = asset->sample_rate / 30;
895                 switch(asset->sample_rate)
896                 {
897                         case 48000:
898                                 if(frame_count % 5 != 0)
899                                         samples += 2;
900                                 break;
901                         case 44100:
902                                 if(frame_count % 300 == 0)
903                                         samples = 1471;
904                                 else if(frame_count % 30 == 0)
905                                         samples = 1470;
906                                 else if(frame_count % 2 == 0)
907                                         samples = 1472;
908                                 else
909                                         samples = 1471;
910                                 break;
911                         case 32000:
912                                 if(frame_count % 30 == 0)
913                                         samples = 1068;
914                                 else if(frame_count % 29 == 0)
915                                         samples = 1067;
916                                 else if(frame_count % 4 == 2)
917                                         samples = 1067;
918                                 else
919                                         samples = 1068;
920                                 break;
921                         default:
922                                 samples = 0;
923                 }
924         }
925         return samples;
947 DVConfigAudio::DVConfigAudio(BC_WindowBase *parent_window, Asset *asset)
948  : BC_Window(PROGRAM_NAME ": Audio Compression",
949         parent_window->get_abs_cursor_x(1),
950         parent_window->get_abs_cursor_y(1),
951         350,
952         250)
954         this->parent_window = parent_window;
955         this->asset = asset;
958 DVConfigAudio::~DVConfigAudio()
963 int DVConfigAudio::create_objects()
965         add_tool(new BC_Title(10, 10, _("There are no audio options for this format")));
966         add_subwindow(new BC_OKButton(this));
967         return 0;
970 int DVConfigAudio::close_event()
972         set_done(0);
973         return 1;
981 DVConfigVideo::DVConfigVideo(BC_WindowBase *parent_window, Asset *asset)
982  : BC_Window(PROGRAM_NAME ": Video Compression",
983         parent_window->get_abs_cursor_x(1),
984         parent_window->get_abs_cursor_y(1),
985         350,
986         250)
988         this->parent_window = parent_window;
989         this->asset = asset;
992 DVConfigVideo::~DVConfigVideo()
997 int DVConfigVideo::create_objects()
999         add_tool(new BC_Title(10, 10, _("There are no video options for this format")));
1000         add_subwindow(new BC_OKButton(this));
1001         return 0;
1004 int DVConfigVideo::close_event()
1006         set_done(0);
1007         return 1;
1011 #endif