r999: maintainers added to README_en.
[cinelerra_cv/mob.git] / cinelerra / filedv.C
blobd7ba80ce81b7e8863a87a6ee6d39a4c47d66a8e7
1 #include "asset.h"
2 #include "bcsignals.h"
3 #include "byteorder.h"
4 #include "dv1394.h"
5 #include "edit.h"
6 #include "file.h"
7 #include "filedv.h"
8 #include "guicast.h"
9 #include "interlacemodes.h"
10 #include "language.h"
11 #include "mutex.h"
12 #include "mwindow.inc"
13 #include "quicktime.h"
14 #include "vframe.h"
15 #include "videodevice.inc"
16 #include "cmodel_permutation.h"
17 #include "mainerror.h"
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <fcntl.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <errno.h>
28 #include <iostream>
30 FileDV::FileDV(Asset *asset, File *file)
31  : FileBase(asset, file)
33         stream = 0;
34         decoder = 0;
35         encoder = 0;
36         audio_encoder = 0;
37         audio_buffer = 0;
38         video_buffer = 0;
39         output_size = 0;
40         video_position = 0;
41         audio_position = 0;
43         audio_sample_buffer = 0;
44         audio_sample_buffer_len = 0;
45         audio_sample_buffer_start = 0;
46         audio_sample_buffer_end = 0;
47         audio_sample_buffer_maxsize = 0;
49         audio_frames_written = 0;
51         if(asset->format == FILE_UNKNOWN)
52                 asset->format = FILE_RAWDV;
53         asset->byte_order = 0;
55         stream_lock = new Mutex("FileDV::stream_lock");
56         decoder_lock = new Mutex("FileDV::decoder_lock");
57         video_position_lock = new Mutex("FileDV::video_position_lock");
60 FileDV::~FileDV()
62         if(stream) close_file();
64         if(decoder) dv_decoder_free(decoder);
65         if(encoder) dv_encoder_free(encoder);
66         if(audio_encoder) dv_encoder_free(audio_encoder);
67         
68         delete stream_lock;
69         delete decoder_lock;
70         delete video_position_lock;
71         
72         delete[] video_buffer;
73         delete[] audio_buffer;
74         
75         if(audio_sample_buffer)
76         {
77                 for(int i = 0; i < asset->channels; i++)
78                         delete[] audio_sample_buffer[i];
79                 delete[] audio_sample_buffer;
80         }
83 void FileDV::get_parameters(BC_WindowBase *parent_window,
84         Asset *asset,
85         BC_WindowBase* &format_window,
86         int audio_options,
87         int video_options)
89         if(audio_options)
90         {
91                 DVConfigAudio *window = new DVConfigAudio(parent_window, asset);
92                 format_window = window;
93                 window->create_objects();
94                 window->run_window();
95                 delete window;
96         }
97         else
98         if(video_options)
99         {
100                 DVConfigVideo *window = new DVConfigVideo(parent_window, asset);
101                 format_window = window;
102                 window->create_objects();
103                 window->run_window();
104                 delete window;
105         }
109 int FileDV::reset_parameters_derived()
111         if(decoder) dv_decoder_free(decoder);
112         if(encoder) dv_encoder_free(encoder);
113         if(audio_encoder) dv_encoder_free(audio_encoder);
114         decoder = 0;
115         encoder = 0;
116         audio_encoder = 0;
118 TRACE("FileDV::reset_parameters_derived 10")
120 TRACE("FileDV::reset_parameters_derived: 20")
121         delete[] audio_buffer;
122         delete[] video_buffer;
123 TRACE("FileDV::reset_parameters_derived: 30")
124         
125         audio_buffer = 0;
126         video_buffer = 0;
127         
128         if(stream) fclose(stream);
129         
130         stream = 0;
131         
132         audio_position = 0;
133         video_position = 0;
134         
135         if(audio_sample_buffer)
136         {
137                 for(int i = 0; i < asset->channels; i++)
138                         delete[] audio_sample_buffer[i];
139                 delete[] audio_sample_buffer;
140         }
141         audio_sample_buffer = 0;
142         audio_sample_buffer_start = 0;
143         audio_sample_buffer_len = 0;
144         audio_sample_buffer_end = 0;
145         audio_sample_buffer_maxsize = 0;
146         
147         audio_frames_written = 0;
148 // output_size gets set in open_file, once we know if the frames are PAL or NTSC
149 // output and input are allocated at the same point.
150         output_size = 0;
151         
152 UNTRACE
153         return 0;
156 int FileDV::open_file(int rd, int wr)
159 TRACE("FileDV::open_file 10")
161         if(wr)
162         {
164 TRACE("FileDV::open_file 20")
166                 
167                 if (!(asset->height == 576 && asset->width == 720 && asset->frame_rate == 25) &&
168                     !(asset->height == 480 && asset->width == 720 && (asset->frame_rate >= 29.96 && asset->frame_rate <= 29.98)))
169                 {
170                         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);
171                         if (asset->height == 480 && asset->width == 720 && asset->frame_rate == 30)
172                         {
173                                 eprintf("Suggestion: Proper frame rate for NTSC DV is 29.97 fps, not 30 fps\n");
174                         }
175                         return 1;       
176                 }   
177                 if (!(asset->channels == 2 && (asset->sample_rate == 48000 || asset->sample_rate == 44100)) &&
178                     !((asset->channels == 4 || asset->channels == 2) && asset->sample_rate == 32000))
179                 {
180                         eprintf("Raw DV format does not support following audio configuration : %i channels at sample rate: %iHz\n", asset->channels, asset->sample_rate);
181                         return 1;
182                 }   
183                   
185                 if((stream = fopen(asset->path, "w+b")) == 0)
186                 {
187                         eprintf("Error while opening \"%s\" for writing. \n%m\n", asset->path);
188                         return 1;
189                 }
190                 
191                 // Create a new encoder
192                 if(encoder) dv_encoder_free(encoder);
193                 encoder = dv_encoder_new(0,0,0);
194                 encoder->vlc_encode_passes = 3;
195                 encoder->static_qno = 0;
196                 encoder->force_dct = DV_DCT_AUTO;
197         
198                 if(audio_encoder) dv_encoder_free(audio_encoder);
199                 audio_encoder = dv_encoder_new(0, 0, 0);
200                 audio_encoder->vlc_encode_passes = 3;
201                 audio_encoder->static_qno = 0;
202                 audio_encoder->force_dct = DV_DCT_AUTO;
203         
204                 if(decoder) dv_decoder_free(decoder);
205                 decoder = dv_decoder_new(0,0,0);
206                 decoder->quality = DV_QUALITY_BEST;
207         
209                 isPAL = (asset->height == 576 ? 1 : 0);
210                 encoder->isPAL = isPAL;
211                 output_size = (isPAL ? DV1394_PAL_FRAME_SIZE : DV1394_NTSC_FRAME_SIZE);
213                 // Compare to 16 / 8 rather than == 16 / 9 in case of floating point
214                 // rounding errors
215                 encoder->is16x9 = asset->aspect_ratio > 16 / 8;
216         }
217         else
218         {
219                 unsigned char *temp;
221 TRACE("FileDV::open_file 30")
223                 struct stat info;
225 TRACE("FileDV::open_file 40")
227                 if((stream = fopen(asset->path, "rb")) == 0)
228                 {
229                         eprintf("Error while opening \"%s\" for reading. \n%m\n", asset->path);
230                         return 1;
231                 }
233                 // temp storage to find out the correct info from the stream.
234                 temp = new unsigned char[DV1394_PAL_FRAME_SIZE];
235                 memset(temp, 0, DV1394_PAL_FRAME_SIZE);
237                 // need file size info to get length.
238                 stat(asset->path, &info);
239                 
240 TRACE("FileDV::open_file 50")
242                 // read the first frame so we can get the stream info from it
243                 // by reading the greatest possible frame size, we ensure we get all the
244                 // data. libdv will determine if it's PAL or NTSC, and input and output
245                 // buffers get allocated accordingly.
246                 fread(temp, DV1394_PAL_FRAME_SIZE, 1, stream);
248 TRACE("FileDV::open_file 60")
250                 if(decoder) dv_decoder_free(decoder);
251                 decoder = dv_decoder_new(0,0,0);
252                 decoder->quality = DV_QUALITY_BEST;
253         
255                 if(dv_parse_header(decoder, temp) > -1 )
256                 {
257                         // define video params first -- we need to find out output_size
258                         // always have video
259                         asset->video_data = 1;
260                         asset->layers = 1;
262                         //TODO: according to the information I found, letterbox and widescreen
263                         //are the same thing; however, libdv provides a function to check
264                         //if the video feed is one of the other. Need to find out if there
265                         //is a difference.
266                         if(dv_format_normal(decoder) != 0) asset->aspect_ratio = (double) 4 / 3;
267                         else asset->aspect_ratio = (double) 16 / 9;
269                         asset->width = decoder->width;
270                         asset->height = decoder->height;
271                         
272                         if(dv_is_progressive(decoder) > 0)
273                                 asset->interlace_mode = BC_ILACE_MODE_NOTINTERLACED;
274                         else
275                                 asset->interlace_mode = BC_ILACE_MODE_BOTTOM_FIRST;
276                         
277                         isPAL = dv_is_PAL(decoder);
278                         
279                         output_size = (isPAL ? DV1394_PAL_FRAME_SIZE : DV1394_NTSC_FRAME_SIZE);
280                         asset->video_length = info.st_size / output_size;
281                         
282                         if(!asset->frame_rate)
283                                 asset->frame_rate = (isPAL ? 25 : 29.97);
284                         strncpy(asset->vcodec, "dvc ", 4);
286                         // see if there are any audio tracks
287                         asset->channels = dv_get_num_channels(decoder);
288                         if(asset->channels > 0)
289                         {
290                                 asset->audio_data = 1;
291                                 asset->sample_rate = dv_get_frequency(decoder);
292                                 // libdv always scales the quantization up to 16 bits for dv_decode_full_audio
293                                 asset->bits = 16;
294                                 asset->audio_length = (int64_t) (info.st_size / output_size / asset->frame_rate * asset->sample_rate);
295                                 strncpy(asset->acodec, "dvc ", 4);
296                         }
297                         else
298                                 asset->audio_data = 0;
299                 }
300                 else
301                 {
302                         asset->audio_data = 0;
303                         asset->video_data = 0;
304                 }
306                 fseeko(stream, 0, SEEK_SET);
307 TRACE("FileDV::open_file 80")
309                 delete[] temp;
310         }
312         // allocate space for audio and video
313         video_buffer = new unsigned char[output_size + 4];
314         audio_buffer = new unsigned char[output_size + 4];
315                         
316 UNTRACE
317         return 0;
320 int FileDV::check_sig(Asset *asset)
322         unsigned char temp[3];
323         FILE *t_stream = fopen(asset->path, "rb");
325         fread(&temp, 3, 1, t_stream);
327         fclose(t_stream);
328         
329         if(temp[0] == 0x1f &&
330                         temp[1] == 0x07 &&
331                         temp[2] == 0x00)
332                 return 1;
334         return 0;
337 int FileDV::close_file_derived()
339         if(stream) fclose(stream);
340         stream = 0;
342         return 0;
345 int64_t FileDV::get_video_position()
347         return video_position;
350 int64_t FileDV::get_audio_position()
352         return audio_position;
355 int FileDV::set_video_position(int64_t x)
357         video_position = x;
358         return 0;
361 int FileDV::set_audio_position(int64_t x)
363         audio_position = x;
364         return 0;
367 int FileDV::audio_samples_copy(double **buffer, int64_t len)
369         // take the buffer and copy it into a queue
370         if(!audio_sample_buffer)
371         {
372                 audio_sample_buffer = new int16_t*[asset->channels];
373                 if(!audio_sample_buffer)
374                 {
375                         fprintf(stderr, "ERROR: Unable to allocate memory for audio_sample_buffer.\n");
376                         return 1;
377                 }
378                 
379                 for(int i = 0; i < asset->channels; i++)
380                 {
381                         audio_sample_buffer[i] = new int16_t[len * 2];
383                         if(!audio_sample_buffer[i])
384                         {
385                                 fprintf(stderr, "ERROR: Unable to allocate memory for "
386                                         "audio_sample_buffer channel %d\n", i);
387                                 return 1;
388                         }
389                 }
390                 audio_sample_buffer_maxsize = len * 2;
391                 audio_sample_buffer_len = 0;
392                 audio_sample_buffer_start = 0;
393                 audio_sample_buffer_end = 0;
394         }
396         if(audio_sample_buffer_maxsize <= audio_sample_buffer_len + len)
397         {
398                 // Allocate double the needed size
399                 for(int i = 0; i < asset->channels; i++)
400                 {
401                         int16_t *tmp = new int16_t[(audio_sample_buffer_len + len) * 2];
402                         if(!tmp)
403                         {
404                                 fprintf(stderr, "ERROR: Unable to reallocate memory for "
405                                         "audio_sample_buffer channel %d\n", i);
406                                 return 1;
407                         }
408                         // Copy everything from audio_sample_buffer into tmp
409                         for(int a = 0, b = audio_sample_buffer_start;
410                                         a < audio_sample_buffer_len;
411                                         a++, b = (b < (audio_sample_buffer_maxsize - 1) ? (b + 1) : 0))
412                         {
413                                 tmp[a] = audio_sample_buffer[i][b];
414                         }
415                         // Free the current buffer, and reassign tmp to audio_sample_buffer[i]
416                         delete[] audio_sample_buffer[i];
417                         audio_sample_buffer[i] = tmp;
418                 }
419                 audio_sample_buffer_start = 0;
420                 audio_sample_buffer_end = audio_sample_buffer_len - 1;
421                 audio_sample_buffer_maxsize = (audio_sample_buffer_len + len) * 2;
422         }
425         for(int i = 0; i < asset->channels; i++)
426         {
427                 if(len + audio_sample_buffer_end < audio_sample_buffer_maxsize)
428                 {
429                         // copy buffer into audio_sample_buffer, straight out (no loop around)
430                         for(int a = 0; a < len; a++)
431                         {
432                                 audio_sample_buffer[i][audio_sample_buffer_end + a] = 
433                                         (buffer[i][a] * 32767);
434                         }
435                         if(i == (asset->channels - 1))
436                                 audio_sample_buffer_end += len;
437                 }
438                 else
439                 {
440                         // Need to loop back to the start of audio_sample_buffer
441                         int copy_size = audio_sample_buffer_maxsize - audio_sample_buffer_end;
443                         for(int a = 0; a < copy_size; a++)
444                                 audio_sample_buffer[i][a + audio_sample_buffer_end] =
445                                         (buffer[i][a] * 32767);
447                         for(int a = 0; a < len - copy_size; a++)
448                                 audio_sample_buffer[i][a] = (buffer[i][a + copy_size] * 32767);
449                         
450                         if(i == (asset->channels - 1))
451                                 audio_sample_buffer_end = len - copy_size;
452                 }
453         }
454         
455         audio_sample_buffer_len += len;
456         
457         return 0;
460 int FileDV::write_samples(double **buffer, int64_t len)
462         if(audio_samples_copy(buffer, len) != 0)
463         {
464                 eprintf("Unable to store sample");
465                 return 1;       
466         }
467         video_position_lock->lock("FileDV::write_samples");
469 TRACE("FileDV::write_samples 200")
470         // Get number of frames to be written. Order of operations is important here;
471         // the buffer length must be multiplied by the frame rate first in case the
472         // number of samples in the buffer is less than the sample rate.
473         int nFrames = MIN(video_position - audio_frames_written,
474                                                         audio_sample_buffer_len * asset->frame_rate / asset->sample_rate);
476         video_position_lock->unlock();
478 TRACE("FileDV::write_samples 210")
479         
480         int16_t **tmp_buf = new int16_t*[asset->channels];
481         for(int a = 0; a < asset->channels; a++)
482                 tmp_buf[a] = new int16_t[asset->sample_rate];
484 TRACE("FileDV::write_samples 220")
485         
486         for(int i = 0; i < nFrames; i++)
487         {
488                 stream_lock->lock("FileDV::write_samples 10");
489                 if(fseeko(stream, (off_t) audio_frames_written * output_size, SEEK_SET) != 0)
490                 {
491                         eprintf("Unable to set audio write position to %lli\n", (off_t) audio_frames_written * output_size);
493                         stream_lock->unlock();
494                         return 1;
495                 }
496                 
497                 if(fread(audio_buffer, output_size, 1, stream) != 1)
498                 {
499                         eprintf("Unable to read from audio buffer file\n");
500                         stream_lock->unlock();
501                         return 1;
502                 }
503                 
504                 stream_lock->unlock();
508 TRACE("FileDV::write_samples 230")
510                 int samples = dv_calculate_samples(audio_encoder, asset->sample_rate,
511                                                                 audio_frames_written);
513                 if(samples > audio_sample_buffer_maxsize - 1 - audio_sample_buffer_start)
514                 {
515 TRACE("FileDV::write_samples 240")
516                         int copy_size = audio_sample_buffer_maxsize - audio_sample_buffer_start - 1;
517                         
518                         for(int a = 0; a < asset->channels; a++)
519                         {
520                                 memcpy(tmp_buf[a], audio_sample_buffer[a] + audio_sample_buffer_start,
521                                         copy_size * sizeof(int16_t));
522                                 memcpy(tmp_buf[a] + copy_size, audio_sample_buffer[a],
523                                         (samples - copy_size) * sizeof(int16_t));
524                         }
525 TRACE("FileDV::write_samples 250")
526                         // Encode the audio into the frame
527                         if(dv_encode_full_audio(audio_encoder, tmp_buf, asset->channels,
528                                 asset->sample_rate, audio_buffer) < 0)
529                         {
530                                 eprintf("ERROR: unable to encode audio frame %d\n", audio_frames_written);
531                         }
532                 }
533                 else
534                 {
535 TRACE("FileDV::write_samples 260")
536                         int16_t **tmp_buf2 = new int16_t*[asset->channels];
537                         for(int a = 0; a < asset->channels; a++)
538                                 tmp_buf2[a] = audio_sample_buffer[a] + audio_sample_buffer_start;
539                         if(dv_encode_full_audio(audio_encoder, tmp_buf2,
540                                 asset->channels, asset->sample_rate, audio_buffer) < 0)
541                         {
542                                 eprintf("ERROR: unable to encode audio frame %d\n", audio_frames_written);
543                                 
544                         }
545                         delete[] tmp_buf2;
546                 }               
547                 
548 TRACE("FileDV::write_samples 270")
550                 stream_lock->lock("FileDV::write_samples 20");
551                 if(fseeko(stream, (off_t) audio_frames_written * output_size, SEEK_SET) != 0)
552                 {
553                         eprintf("ERROR: Unable to relocate for audio write to %lli\n", (off_t) audio_frames_written * output_size);
554                         stream_lock->unlock();
555                         return 1;
556                 }
557                 
558                 if(fwrite(audio_buffer, output_size, 1, stream) != 1)
559                 {
560                         eprintf("Unable to write audio to audio buffer\n");
561                         stream_lock->unlock();
562                         return 1;
563                 }
565                 stream_lock->unlock();
566                 
567                 audio_frames_written++;
568                 audio_sample_buffer_len -= samples;
569                 audio_sample_buffer_start += samples;
570                 if(audio_sample_buffer_start >= audio_sample_buffer_maxsize)
571                         audio_sample_buffer_start -= audio_sample_buffer_maxsize;
572         }
574 TRACE("FileDV::write_samples 280")
576         for(int a = 0; a < asset->channels; a++)
577                 delete[] tmp_buf[a];
578         delete[] tmp_buf;
580 TRACE("FileDV::write_samples 290")
583 UNTRACE
585         return 0;
588 int FileDV::write_frames(VFrame ***frames, int len)
590         int result = 0;
592         if(stream == 0) return 1;
594         for(int j = 0; j < len && !result; j++)
595         {
596                 VFrame *temp_frame = frames[0][j];
598 //printf("FileDV::write_frames: color_model %i\n", temp_frame->get_color_model());
599                         switch(temp_frame->get_color_model())
600                         {
601                                 case BC_COMPRESSED:
602                                         memcpy(video_buffer, temp_frame->get_data(), output_size);
603                                         break;
604                                 case BC_YUV422:
605 //printf("FileDV::write_frames: 4\n");
606                                         dv_encode_full_frame(encoder, temp_frame->get_rows(),
607                                                 e_dv_color_yuv, video_buffer);
608                                         break;
609                                 case BC_RGB888:
610 //printf("FileDV::write_frames: 5\n");
611                                         dv_encode_full_frame(encoder, temp_frame->get_rows(),
612                                                 e_dv_color_rgb, video_buffer);
613                                         break;
614                                 default:
615                                         unsigned char *data = new unsigned char[asset->height * asset->width * 2];
616                                         unsigned char **cmodel_buf = new unsigned char *[asset->height];
617 //printf("FileDV::write_frames: 6\n");
618                                         unsigned char **row_pointers = temp_frame->get_rows();
619                                         for(int i = 0; i < asset->height; i++)
620                                                 cmodel_buf[i] = data + asset->width * 2 * i;
621                                         
622                                         cmodel_transfer(cmodel_buf,
623                                                 row_pointers,
624                                                 cmodel_buf[0],
625                                                 cmodel_buf[1],
626                                                 cmodel_buf[2],
627                                                 row_pointers[0],
628                                                 row_pointers[1],
629                                                 row_pointers[2],
630                                                 0,
631                                                 0,
632                                                 asset->width,
633                                                 asset->height,
634                                                 0,
635                                                 0,
636                                                 asset->width,
637                                                 asset->height,
638                                                 temp_frame->get_color_model(),
639                                                 BC_YUV422,
640                                                 0,
641                                                 asset->width,
642                                                 asset->width);
644                                         dv_encode_full_frame(encoder, cmodel_buf,
645                                                 e_dv_color_yuv, video_buffer);
647                                         delete[] cmodel_buf;
648                                         delete[] data;
649                                         break;
650                         }
651 //printf("FileDV::write_frames: 7\n");
653                 // This is the only thread that modifies video_position,
654                 // so video_position_lock can remain unlocked for reads.
655                 stream_lock->lock("FileDV::write_frames");
656                 if(fseeko(stream, (off_t) video_position * output_size, SEEK_SET) != 0)
657                 {
658                         eprintf("Unable to seek file to %lli\n", (off_t)(video_position * output_size));
659                 }
660                 if(fwrite(video_buffer, output_size, 1, stream) < 1)
661                 {
662                         eprintf("Unable to write video data to video buffer");
663                 }
664                 stream_lock->unlock();
665                 
666                 video_position_lock->lock();
667                 video_position++;
668                 video_position_lock->unlock();
669         }
670         
671         return 0;
674 int FileDV::read_compressed_frame(VFrame *buffer)
676         int64_t result;
677         if(stream == 0) return 0;
679         if (fseeko(stream, (off_t) video_position * output_size, SEEK_SET))
680         {
681                 eprintf("Unable to seek file to %lli\n", (off_t)(video_position * output_size));
682         }
683         result = fread(buffer->get_data(), output_size, 1, stream);
684         video_position++;
686         buffer->set_compressed_size(result);
687         
688         return result != 0;
691 int FileDV::write_compressed_frame(VFrame *buffer)
693         int result = 0;
694         if(stream == 0) return 0;
696         if (fseeko(stream, (off_t) video_position * output_size, SEEK_SET))
697         {
698                 eprintf("Unable to seek file to %lli\n", (off_t)(video_position * output_size));
699         }
700         result = fwrite(buffer->get_data(), buffer->get_compressed_size(), 1, stream);
701         video_position++;
702         return result != 0;
705 int64_t FileDV::compressed_frame_size()
707         return output_size;
710 int FileDV::read_samples(double *buffer, int64_t len)
712         int count = 0;
713         int result = 0;
714         int frame_count = get_audio_frame(audio_position);
715         int offset = get_audio_offset(audio_position);
716         
717         stream_lock->lock("FileDV::read_samples");
718         if(stream == 0)
719         {
720                 stream_lock->unlock();
721                 return 1;
722         }
723         stream_lock->unlock();
725         // If the sample rate is 32 kHz, and the bitsize is 12, libdv
726         // requires we have space allocated for 4 channels even if
727         // the data only contains two channels.
729         // decoder will exist since it is not free'd after open_file
730         int channels = (asset->sample_rate == 32000 && decoder->audio->quantization == 12) ? 4 : 2;
732         int16_t **out_buffer = new int16_t*[channels];
733         for(int i = 0; i < channels; i++)
734                 out_buffer[i] = new int16_t[DV_AUDIO_MAX_SAMPLES];
736         while(count < len)
737         {
738                 stream_lock->lock();
739                 
740                 if(fseeko(stream, (off_t) frame_count * output_size, SEEK_SET) != 0)
741                 {
742                         stream_lock->unlock();
743                         result = 1;
744                         break;
745                 }
746                 
747                 if(fread(audio_buffer, output_size, 1, stream) < 1)
748                 {
749                         stream_lock->unlock();
750                         result = 1;
751                         break;
752                 }
754                 stream_lock->unlock();
755                 
756                 frame_count++;
757                 
758                 decoder_lock->lock("FileDV::read_samples");
759                 
760                 if(dv_decode_full_audio(decoder, audio_buffer, out_buffer) < 0)
761                 {
762                         eprintf("Error decoding audio frame %d\n", frame_count - 1);
763                 }
765                 int end = dv_get_num_samples(decoder);
766                 decoder_lock->unlock();
768                 if(len - count + offset < end)
769                         end = len - count + offset;
771                 for(int i = offset; i < end; i++)
772                         buffer[count++] = out_buffer[file->current_channel][i] / 32767.0;
774                 offset = 0;
775         }
776         
777         for(int i = 0; i < channels; i++)
778                 delete[] out_buffer[i];
779         delete[] out_buffer;
781         audio_position += len;
782         
783         return result;
786 int FileDV::read_frame(VFrame *frame)
788         if(stream == 0) return 1;
789         int pitches[3] = {720 * 2, 0, 0};
791 TRACE("FileDV::read_frame 1")
792         unsigned char **row_pointers = frame->get_rows();
795 TRACE("FileDV::read_frame 10")
797         // Seek to video position
798         stream_lock->lock("FileDV::read_frame");
799         if(fseeko(stream, (off_t) video_position * output_size, SEEK_SET) < 0)
800         {
801                 eprintf("Unable to seek file to %lli", (off_t)(video_position * output_size));
802                 stream_lock->unlock();
803                 return 1;
804         }
805         fread(video_buffer, output_size, 1, stream);
806         stream_lock->unlock();
807         video_position++;
808         
810 TRACE("FileDV::read_frame 20")
812         switch(frame->get_color_model())
813         {
814                 case BC_COMPRESSED:
816 TRACE("FileDV::read_frame 30")
818                         frame->allocate_compressed_data(output_size);
819                         frame->set_compressed_size(output_size);
820                         memcpy(frame->get_data(), video_buffer, output_size);
821                         break;
822                 case BC_RGB888:
824 TRACE("FileDV::read_frame 40")
826                         pitches[0] = 720 * 3;
827                         decoder_lock->lock("FileDV::read_frame 10");
828                         dv_decode_full_frame(decoder, video_buffer, e_dv_color_rgb,
829                                 row_pointers, pitches);
830                         decoder_lock->unlock();
831                         break;
832                 case BC_YUV422:
833 TRACE("FileDV::read_frame 50")
834                         decoder_lock->lock("FileDV::read_frame 20");
835                         dv_decode_full_frame(decoder, video_buffer, e_dv_color_yuv,
836                                 row_pointers, pitches);
837                         decoder_lock->unlock();
838                         break;
840                 default:
841                         unsigned char *data = new unsigned char[asset->height * asset->width * 2];
842                         unsigned char **temp_pointers = new unsigned char*[asset->height];
844                         for(int i = 0; i < asset->height; i++)
845                                 temp_pointers[i] = data + asset->width * 2 * i;
846                                 
847                         
848 TRACE("FileDV::read_frame 69")
850                         decoder_lock->lock("FileDV::read_frame 30");
851                         dv_decode_full_frame(decoder, video_buffer, e_dv_color_yuv,
852                                 temp_pointers, pitches);
853                         decoder_lock->unlock();
855 TRACE("FileDV::read_frame 70")
857                         cmodel_transfer(row_pointers,
858                                 temp_pointers,
859                                 row_pointers[0],
860                                 row_pointers[1],
861                                 row_pointers[2],
862                                 temp_pointers[0],
863                                 temp_pointers[1],
864                                 temp_pointers[2],
865                                 0,
866                                 0,
867                                 asset->width,
868                                 asset->height,
869                                 0,
870                                 0,
871                                 asset->width,
872                                 asset->height,
873                                 BC_YUV422,
874                                 frame->get_color_model(),
875                                 0,
876                                 asset->width,
877                                 asset->width);
878                         
879                         //for(int i = 0; i < asset->height; i++)
880                         //      delete[] temp_pointers[i];
881                         delete[] temp_pointers;
882                         delete[] data;
884                         
885                         break;
886         }
888 TRACE("FileDV::read_frame 80")
890 UNTRACE
892         return 0;       
895 int FileDV::colormodel_supported(int colormodel)
897         return colormodel;
900 int FileDV::can_copy_from(Edit *edit, int64_t position)
902         if(edit->asset->format == FILE_RAWDV ||
903                         (edit->asset->format == FILE_MOV &&
904                                 (match4(edit->asset->vcodec, QUICKTIME_DV) ||
905                                 match4(edit->asset->vcodec, QUICKTIME_DVSD) ||
906                                 match4(edit->asset->vcodec, QUICKTIME_DVCP))))
907                 return 1;
909         return 0;
912 int FileDV::get_best_colormodel(Asset *asset, int driver)
914         switch(driver)
915         {
916                 case PLAYBACK_X11:
917                         return BC_RGB888;
918                         break;
919                 case PLAYBACK_X11_XV:
920                         return BC_YUV422;
921                         break;
922                 case PLAYBACK_DV1394:
923                 case PLAYBACK_FIREWIRE:
924                         return BC_COMPRESSED;
925                         break;
926                 case PLAYBACK_LML:
927                 case PLAYBACK_BUZ:
928                         return BC_YUV422P;
929                         break;
930                 case VIDEO4LINUX:
931                 case VIDEO4LINUX2:
932                 case CAPTURE_BUZ:
933                 case CAPTURE_LML:
934                 case VIDEO4LINUX2JPEG:
935                         return BC_YUV422;
936                         break;
937                 case CAPTURE_FIREWIRE:
938                         return BC_COMPRESSED;
939                         break;
940         }
941         return BC_RGB888;
944 int FileDV::get_audio_frame(int64_t pos)
946         return (double) pos * asset->frame_rate / asset->sample_rate;
949 // Get the sample offset from the frame start reported by get_audio_frame
950 int FileDV::get_audio_offset(int64_t pos)
952         int frame = get_audio_frame(pos);
953                 
954         // Samples needed from last frame
955         return  pos - frame * asset->sample_rate / asset->frame_rate;
978 DVConfigAudio::DVConfigAudio(BC_WindowBase *parent_window, Asset *asset)
979  : BC_Window(PROGRAM_NAME ": Audio Compression",
980         parent_window->get_abs_cursor_x(1),
981         parent_window->get_abs_cursor_y(1),
982         350,
983         250)
985         this->parent_window = parent_window;
986         this->asset = asset;
989 DVConfigAudio::~DVConfigAudio()
994 int DVConfigAudio::create_objects()
996         add_tool(new BC_Title(10, 10, _("There are no audio options for this format")));
997         add_subwindow(new BC_OKButton(this));
998         return 0;
1001 int DVConfigAudio::close_event()
1003         set_done(0);
1004         return 1;
1012 DVConfigVideo::DVConfigVideo(BC_WindowBase *parent_window, Asset *asset)
1013  : BC_Window(PROGRAM_NAME ": Video Compression",
1014         parent_window->get_abs_cursor_x(1),
1015         parent_window->get_abs_cursor_y(1),
1016         350,
1017         250)
1019         this->parent_window = parent_window;
1020         this->asset = asset;
1023 DVConfigVideo::~DVConfigVideo()
1028 int DVConfigVideo::create_objects()
1030         add_tool(new BC_Title(10, 10, _("There are no video options for this format")));
1031         add_subwindow(new BC_OKButton(this));
1032         return 0;
1035 int DVConfigVideo::close_event()
1037         set_done(0);
1038         return 1;