r802: Remove renderframfsclient and renderfarmfsserver .h and .C from Makefile.am...
[cinelerra_cv/mob.git] / cinelerra / filedv.C
blob5b663b426d2ad0c95cd34ee5ea121a836e81fb30
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 "mwindow.inc"
12 #include "quicktime.h"
13 #include "vframe.h"
14 #include "videodevice.inc"
15 #include "cmodel_permutation.h"
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <fcntl.h>
20 #include <unistd.h>
21 #include <string.h>
22 #include <errno.h>
24 #include <iostream>
26 FileDV::FileDV(Asset *asset, File *file)
27  : FileBase(asset, file)
29         stream = 0;
30         decoder = 0;
31         encoder = 0;
32         audio_encoder = 0;
33         audio_buffer = 0;
34         video_buffer = 0;
35         output_size = 0;
36         video_position = 0;
37         audio_position = 0;
39         audio_sample_buffer = 0;
40         audio_sample_buffer_len = 0;
41         audio_sample_buffer_start = 0;
42         audio_sample_buffer_end = 0;
43         audio_sample_buffer_maxsize = 0;
45         audio_frames_written = 0;
47         if(asset->format == FILE_UNKNOWN)
48                 asset->format = FILE_RAWDV;
49         asset->byte_order = 0;
51         stream_lock = new Mutex("FileDV::stream_lock");
52         decoder_lock = new Mutex("FileDV::decoder_lock");
53         video_position_lock = new Mutex("FileDV::video_position_lock");
56 FileDV::~FileDV()
58         if(stream) close_file();
60         if(decoder) dv_decoder_free(decoder);
61         if(encoder) dv_encoder_free(encoder);
62         if(audio_encoder) dv_encoder_free(audio_encoder);
63         
64         delete stream_lock;
65         delete decoder_lock;
66         delete video_position_lock;
67         
68         delete[] video_buffer;
69         delete[] audio_buffer;
70         
71         if(audio_sample_buffer)
72         {
73                 for(int i = 0; i < asset->channels; i++)
74                         delete[] audio_sample_buffer[i];
75                 delete[] audio_sample_buffer;
76         }
79 void FileDV::get_parameters(BC_WindowBase *parent_window,
80         Asset *asset,
81         BC_WindowBase* &format_window,
82         int audio_options,
83         int video_options)
85         if(audio_options)
86         {
87                 DVConfigAudio *window = new DVConfigAudio(parent_window, asset);
88                 format_window = window;
89                 window->create_objects();
90                 window->run_window();
91                 delete window;
92         }
93         else
94         if(video_options)
95         {
96                 DVConfigVideo *window = new DVConfigVideo(parent_window, asset);
97                 format_window = window;
98                 window->create_objects();
99                 window->run_window();
100                 delete window;
101         }
105 int FileDV::reset_parameters_derived()
107         if(decoder) dv_decoder_free(decoder);
108         if(encoder) dv_encoder_free(encoder);
109         if(audio_encoder) dv_encoder_free(audio_encoder);
110         decoder = 0;
111         encoder = 0;
112         audio_encoder = 0;
114 TRACE("FileDV::reset_parameters_derived 10")
116 TRACE("FileDV::reset_parameters_derived: 20")
117         delete[] audio_buffer;
118         delete[] video_buffer;
119 TRACE("FileDV::reset_parameters_derived: 30")
120         
121         audio_buffer = 0;
122         video_buffer = 0;
123         
124         if(stream) fclose(stream);
125         
126         stream = 0;
127         
128         audio_position = 0;
129         video_position = 0;
130         
131         if(audio_sample_buffer)
132         {
133                 for(int i = 0; i < asset->channels; i++)
134                         delete[] audio_sample_buffer[i];
135                 delete[] audio_sample_buffer;
136         }
137         audio_sample_buffer = 0;
138         audio_sample_buffer_start = 0;
139         audio_sample_buffer_len = 0;
140         audio_sample_buffer_end = 0;
141         audio_sample_buffer_maxsize = 0;
142         
143         audio_frames_written = 0;
144 // output_size gets set in open_file, once we know if the frames are PAL or NTSC
145 // output and input are allocated at the same point.
146         output_size = 0;
147         
148 UNTRACE
149         return 0;
152 int FileDV::open_file(int rd, int wr)
155 TRACE("FileDV::open_file 10")
157         if(wr)
158         {
160 TRACE("FileDV::open_file 20")
162                 
163                 if (!(asset->height == 576 && asset->width == 720 && asset->frame_rate == 25) &&
164                     !(asset->height == 480 && asset->width == 720 && (asset->frame_rate >= 29.96 && asset->frame_rate <= 29.98)))
165                 {
166                         printf("Resolution not supported for dv: %ix%i framerate: %f\n", asset->width, asset->height, asset->frame_rate); 
167                         if (asset->height == 480 && asset->width == 720 && asset->frame_rate == 30)
168                         {
169                                 printf("Suggestion: Proper frame rate for NTSC DV is 29.97\n");
170                         }
171                         return 1;       
172                 }   
173                 if (!(asset->channels == 2 && (asset->sample_rate == 48000 || asset->sample_rate == 44100)) &&
174                     !((asset->channels == 4 || asset->channels == 2) && asset->sample_rate == 32000))
175                 {
176                         printf("Audio configuration not supported for dv: channels: %i, sample rate: %i\n", asset->channels, asset->sample_rate); 
177                         return 1;       
178                 }   
179                   
180                 
181                     
182                     
184                 if((stream = fopen(asset->path, "w+b")) == 0)
185                 {
186                         perror(_("FileDV::open_file rdwr"));
187                         return 1;
188                 }
189                 
190                 // Create a new encoder
191                 if(encoder) dv_encoder_free(encoder);
192                 encoder = dv_encoder_new(0,0,0);
193                 encoder->vlc_encode_passes = 3;
194                 encoder->static_qno = 0;
195                 encoder->force_dct = DV_DCT_AUTO;
196         
197                 if(audio_encoder) dv_encoder_free(audio_encoder);
198                 audio_encoder = dv_encoder_new(0, 0, 0);
199                 audio_encoder->vlc_encode_passes = 3;
200                 audio_encoder->static_qno = 0;
201                 audio_encoder->force_dct = DV_DCT_AUTO;
202         
203                 if(decoder) dv_decoder_free(decoder);
204                 decoder = dv_decoder_new(0,0,0);
205                 decoder->quality = DV_QUALITY_BEST;
206         
208                 isPAL = (asset->height == 576 ? 1 : 0);
209                 encoder->isPAL = isPAL;
210                 output_size = (isPAL ? DV1394_PAL_FRAME_SIZE : DV1394_NTSC_FRAME_SIZE);
212                 // Compare to 16 / 8 rather than == 16 / 9 in case of floating point
213                 // rounding errors
214                 encoder->is16x9 = asset->aspect_ratio > 16 / 8;
215         }
216         else
217         {
218                 unsigned char *temp;
220 TRACE("FileDV::open_file 30")
222                 struct stat info;
224 TRACE("FileDV::open_file 40")
226                 if((stream = fopen(asset->path, "rb")) == 0)
227                 {
228                         perror(_("FileDV::open_file rd"));
229                         return 1;
230                 }
232                 // temp storage to find out the correct info from the stream.
233                 temp = new unsigned char[DV1394_PAL_FRAME_SIZE];
234                 memset(temp, 0, DV1394_PAL_FRAME_SIZE);
236                 // need file size info to get length.
237                 stat(asset->path, &info);
238                 
239 TRACE("FileDV::open_file 50")
241                 // read the first frame so we can get the stream info from it
242                 // by reading the greatest possible frame size, we ensure we get all the
243                 // data. libdv will determine if it's PAL or NTSC, and input and output
244                 // buffers get allocated accordingly.
245                 fread(temp, DV1394_PAL_FRAME_SIZE, 1, stream);
247 TRACE("FileDV::open_file 60")
249                 if(decoder) dv_decoder_free(decoder);
250                 decoder = dv_decoder_new(0,0,0);
251                 decoder->quality = DV_QUALITY_BEST;
252         
254                 if(dv_parse_header(decoder, temp) > -1 )
255                 {
256                         // define video params first -- we need to find out output_size
257                         // always have video
258                         asset->video_data = 1;
259                         asset->layers = 1;
261                         //TODO: according to the information I found, letterbox and widescreen
262                         //are the same thing; however, libdv provides a function to check
263                         //if the video feed is one of the other. Need to find out if there
264                         //is a difference.
265                         if(dv_format_normal(decoder) != 0) asset->aspect_ratio = (double) 4 / 3;
266                         else asset->aspect_ratio = (double) 16 / 9;
268                         asset->width = decoder->width;
269                         asset->height = decoder->height;
270                         
271                         if(dv_is_progressive(decoder) > 0)
272                                 asset->interlace_mode = BC_ILACE_MODE_NOTINTERLACED;
273                         else
274                                 asset->interlace_mode = BC_ILACE_MODE_BOTTOM_FIRST;
275                         
276                         isPAL = dv_is_PAL(decoder);
277                         
278                         output_size = (isPAL ? DV1394_PAL_FRAME_SIZE : DV1394_NTSC_FRAME_SIZE);
279                         asset->video_length = info.st_size / output_size;
280                         
281                         if(!asset->frame_rate)
282                                 asset->frame_rate = (isPAL ? 25 : 29.97);
283                         strncpy(asset->vcodec, "dvc ", 4);
285                         // see if there are any audio tracks
286                         asset->channels = dv_get_num_channels(decoder);
287                         if(asset->channels > 0)
288                         {
289                                 asset->audio_data = 1;
290                                 asset->sample_rate = dv_get_frequency(decoder);
291                                 // libdv always scales the quantization up to 16 bits for dv_decode_full_audio
292                                 asset->bits = 16;
293                                 asset->audio_length = (int64_t) (info.st_size / output_size / asset->frame_rate * asset->sample_rate);
294                                 strncpy(asset->acodec, "dvc ", 4);
295                         }
296                         else
297                                 asset->audio_data = 0;
298                 }
299                 else
300                 {
301                         asset->audio_data = 0;
302                         asset->video_data = 0;
303                 }
305                 fseeko(stream, 0, SEEK_SET);
306 TRACE("FileDV::open_file 80")
308                 delete[] temp;
309         }
311         // allocate space for audio and video
312         video_buffer = new unsigned char[output_size + 4];
313         audio_buffer = new unsigned char[output_size + 4];
314                         
315 UNTRACE
316         return 0;
319 int FileDV::check_sig(Asset *asset)
321         unsigned char temp[3];
322         FILE *t_stream = fopen(asset->path, "rb");
324         fread(&temp, 3, 1, t_stream);
326         fclose(t_stream);
327         
328         if(temp[0] == 0x1f &&
329                         temp[1] == 0x07 &&
330                         temp[2] == 0x00)
331                 return 1;
333         return 0;
336 int FileDV::close_file_derived()
338         if(stream) fclose(stream);
339         stream = 0;
341         return 0;
344 int64_t FileDV::get_video_position()
346         return video_position;
349 int64_t FileDV::get_audio_position()
351         return audio_position;
354 int FileDV::set_video_position(int64_t x)
356         video_position = x;
357         return 0;
360 int FileDV::set_audio_position(int64_t x)
362         audio_position = x;
363         return 0;
366 int FileDV::audio_samples_copy(double **buffer, int64_t len)
368         // take the buffer and copy it into a queue
369         if(!audio_sample_buffer)
370         {
371                 audio_sample_buffer = new int16_t*[asset->channels];
372                 if(!audio_sample_buffer)
373                 {
374                         fprintf(stderr, "ERROR: Unable to allocate memory for audio_sample_buffer.\n");
375                         return 1;
376                 }
377                 
378                 for(int i = 0; i < asset->channels; i++)
379                 {
380                         audio_sample_buffer[i] = new int16_t[len * 2];
382                         if(!audio_sample_buffer[i])
383                         {
384                                 fprintf(stderr, "ERROR: Unable to allocate memory for "
385                                         "audio_sample_buffer channel %d\n", i);
386                                 return 1;
387                         }
388                 }
389                 audio_sample_buffer_maxsize = len * 2;
390                 audio_sample_buffer_len = 0;
391                 audio_sample_buffer_start = 0;
392                 audio_sample_buffer_end = 0;
393         }
395         if(audio_sample_buffer_maxsize <= audio_sample_buffer_len + len)
396         {
397                 // Allocate double the needed size
398                 for(int i = 0; i < asset->channels; i++)
399                 {
400                         int16_t *tmp = new int16_t[(audio_sample_buffer_len + len) * 2];
401                         if(!tmp)
402                         {
403                                 fprintf(stderr, "ERROR: Unable to reallocate memory for "
404                                         "audio_sample_buffer channel %d\n", i);
405                                 return 1;
406                         }
407                         // Copy everything from audio_sample_buffer into tmp
408                         for(int a = 0, b = audio_sample_buffer_start;
409                                         a < audio_sample_buffer_len;
410                                         a++, b = (b < (audio_sample_buffer_maxsize - 1) ? (b + 1) : 0))
411                         {
412                                 tmp[a] = audio_sample_buffer[i][b];
413                         }
414                         // Free the current buffer, and reassign tmp to audio_sample_buffer[i]
415                         delete[] audio_sample_buffer[i];
416                         audio_sample_buffer[i] = tmp;
417                 }
418                 audio_sample_buffer_start = 0;
419                 audio_sample_buffer_end = audio_sample_buffer_len - 1;
420                 audio_sample_buffer_maxsize = (audio_sample_buffer_len + len) * 2;
421         }
424         for(int i = 0; i < asset->channels; i++)
425         {
426                 if(len + audio_sample_buffer_end < audio_sample_buffer_maxsize)
427                 {
428                         // copy buffer into audio_sample_buffer, straight out (no loop around)
429                         for(int a = 0; a < len; a++)
430                         {
431                                 audio_sample_buffer[i][audio_sample_buffer_end + a] = 
432                                         (buffer[i][a] * 32767);
433                         }
434                         if(i == (asset->channels - 1))
435                                 audio_sample_buffer_end += len;
436                 }
437                 else
438                 {
439                         // Need to loop back to the start of audio_sample_buffer
440                         int copy_size = audio_sample_buffer_maxsize - audio_sample_buffer_end;
442                         for(int a = 0; a < copy_size; a++)
443                                 audio_sample_buffer[i][a + audio_sample_buffer_end] =
444                                         (buffer[i][a] * 32767);
446                         for(int a = 0; a < len - copy_size; a++)
447                                 audio_sample_buffer[i][a] = (buffer[i][a + copy_size] * 32767);
448                         
449                         if(i == (asset->channels - 1))
450                                 audio_sample_buffer_end = len - copy_size;
451                 }
452         }
453         
454         audio_sample_buffer_len += len;
455         
456         return 0;
459 int FileDV::write_samples(double **buffer, int64_t len)
461         if(audio_samples_copy(buffer, len) != 0)
462         {
463                 fprintf(stderr, "ERROR: Unable to store sample for FileDV::write_samples\n");
464                 return 1;       
465         }
466         video_position_lock->lock("FileDV::write_samples");
468 TRACE("FileDV::write_samples 200")
469         // Get number of frames to be written. Order of operations is important here;
470         // the buffer length must be multiplied by the frame rate first in case the
471         // number of samples in the buffer is less than the sample rate.
472         int nFrames = MIN(video_position - audio_frames_written,
473                                                         audio_sample_buffer_len * asset->frame_rate / asset->sample_rate);
475         video_position_lock->unlock();
477 TRACE("FileDV::write_samples 210")
478         
479         int16_t **tmp_buf = new int16_t*[asset->channels];
480         for(int a = 0; a < asset->channels; a++)
481                 tmp_buf[a] = new int16_t[asset->sample_rate];
483 TRACE("FileDV::write_samples 220")
484         
485         for(int i = 0; i < nFrames; i++)
486         {
487                 stream_lock->lock("FileDV::write_samples 10");
488                 if(fseeko(stream, (off_t) audio_frames_written * output_size, SEEK_SET) != 0)
489                 {
490                         fprintf(stderr, "ERROR: Unable to set audio write position to %lli\n", (off_t) audio_frames_written * output_size);
491                         stream_lock->unlock();
492                         return 1;
493                 }
494                 
495                 if(fread(audio_buffer, output_size, 1, stream) != 1)
496                 {
497                         fprintf(stderr, "ERROR: Unable to read from file\n");
498                         stream_lock->unlock();
499                         return 1;
500                 }
501                 
502                 stream_lock->unlock();
506 TRACE("FileDV::write_samples 230")
508                 int samples = dv_calculate_samples(audio_encoder, asset->sample_rate,
509                                                                 audio_frames_written);
511                 if(samples > audio_sample_buffer_maxsize - 1 - audio_sample_buffer_start)
512                 {
513 TRACE("FileDV::write_samples 240")
514                         int copy_size = audio_sample_buffer_maxsize - audio_sample_buffer_start - 1;
515                         
516                         for(int a = 0; a < asset->channels; a++)
517                         {
518                                 memcpy(tmp_buf[a], audio_sample_buffer[a] + audio_sample_buffer_start,
519                                         copy_size);
520                                 memcpy(tmp_buf[a] + copy_size, audio_sample_buffer[a],
521                                         samples - copy_size);
522                         }
523 TRACE("FileDV::write_samples 250")
524                         // Encode the audio into the frame
525                         if(dv_encode_full_audio(audio_encoder, tmp_buf, asset->channels,
526                                 asset->sample_rate, audio_buffer) < 0)
527                         {
528                                 fprintf(stderr, "ERROR: unable to encode audio frame %d\n", audio_frames_written);
529                         }
530                 }
531                 else
532                 {
533 TRACE("FileDV::write_samples 260")
534                         int16_t **tmp_buf2 = new int16_t*[asset->channels];
535                         for(int a = 0; a < asset->channels; a++)
536                                 tmp_buf2[a] = audio_sample_buffer[a] + audio_sample_buffer_start;
537                         if(dv_encode_full_audio(audio_encoder, tmp_buf2,
538                                 asset->channels, asset->sample_rate, audio_buffer) < 0)
539                         {
540                                 fprintf(stderr, "ERROR: unable to encode audio frame %d\n", audio_frames_written);
541                         }
542                         delete[] tmp_buf2;
543                 }               
544                 
545 TRACE("FileDV::write_samples 270")
547                 stream_lock->lock("FileDV::write_samples 20");
548                 if(fseeko(stream, (off_t) audio_frames_written * output_size, SEEK_SET) != 0)
549                 {
550                         fprintf(stderr, "ERROR: Unable to relocate for audio write to %lli\n", (off_t) audio_frames_written * output_size);
551                         stream_lock->unlock();
552                         return 1;
553                 }
554                 
555                 if(fwrite(audio_buffer, output_size, 1, stream) != 1)
556                 {
557                         fprintf(stderr, "ERROR: Unable to write audio\n");
558                         stream_lock->unlock();
559                         return 1;
560                 }
562                 stream_lock->unlock();
563                 
564                 audio_frames_written++;
565                 audio_sample_buffer_len -= samples;
566                 audio_sample_buffer_start += samples;
567                 if(audio_sample_buffer_start >= audio_sample_buffer_maxsize)
568                         audio_sample_buffer_start -= audio_sample_buffer_maxsize;
569         }
571 TRACE("FileDV::write_samples 280")
573         for(int a = 0; a < asset->channels; a++)
574                 delete[] tmp_buf[a];
575         delete[] tmp_buf;
577 TRACE("FileDV::write_samples 290")
580 UNTRACE
582         return 0;
585 int FileDV::write_frames(VFrame ***frames, int len)
587         int result = 0;
589         if(stream == 0) return 1;
591         for(int j = 0; j < len && !result; j++)
592         {
593                 VFrame *temp_frame = frames[0][j];
595 //printf("FileDV::write_frames: color_model %i\n", temp_frame->get_color_model());
596                         switch(temp_frame->get_color_model())
597                         {
598                                 case BC_COMPRESSED:
599                                         memcpy(video_buffer, temp_frame->get_data(), output_size);
600                                         break;
601                                 case BC_YUV422:
602 //printf("FileDV::write_frames: 4\n");
603                                         dv_encode_full_frame(encoder, temp_frame->get_rows(),
604                                                 e_dv_color_yuv, video_buffer);
605                                         break;
606                                 case BC_RGB888:
607 //printf("FileDV::write_frames: 5\n");
608                                         dv_encode_full_frame(encoder, temp_frame->get_rows(),
609                                                 e_dv_color_rgb, video_buffer);
610                                         break;
611                                 default:
612                                         unsigned char *data = new unsigned char[asset->height * asset->width * 2];
613                                         unsigned char **cmodel_buf = new unsigned char *[asset->height];
614 //printf("FileDV::write_frames: 6\n");
615                                         unsigned char **row_pointers = temp_frame->get_rows();
616                                         for(int i = 0; i < asset->height; i++)
617                                                 cmodel_buf[i] = data + asset->width * 2 * i;
618                                         
619                                         cmodel_transfer(cmodel_buf,
620                                                 row_pointers,
621                                                 cmodel_buf[0],
622                                                 cmodel_buf[1],
623                                                 cmodel_buf[2],
624                                                 row_pointers[0],
625                                                 row_pointers[1],
626                                                 row_pointers[2],
627                                                 0,
628                                                 0,
629                                                 asset->width,
630                                                 asset->height,
631                                                 0,
632                                                 0,
633                                                 asset->width,
634                                                 asset->height,
635                                                 temp_frame->get_color_model(),
636                                                 BC_YUV422,
637                                                 0,
638                                                 asset->width,
639                                                 asset->width);
641                                         dv_encode_full_frame(encoder, cmodel_buf,
642                                                 e_dv_color_yuv, video_buffer);
644                                         delete[] cmodel_buf;
645                                         delete[] data;
646                                         break;
647                         }
648 //printf("FileDV::write_frames: 7\n");
650                 // This is the only thread that modifies video_position,
651                 // so video_position_lock can remain unlocked for reads.
652                 stream_lock->lock("FileDV::write_frames");
653                 if(fseeko(stream, (off_t) video_position * output_size, SEEK_SET) != 0)
654                 {
655                         fprintf(stderr, "FileDV::write_frames: Unable to seek file to %lli\n", (off_t)(video_position * output_size));
656                 }
657                 if(fwrite(video_buffer, output_size, 1, stream) < 1)
658                 {
659                         fprintf(stderr, "FileDV::write_frames: Unable to write video data.\n");         
660                 }
661                 stream_lock->unlock();
662                 
663                 video_position_lock->lock();
664                 video_position++;
665                 video_position_lock->unlock();
666         }
667         
668         return 0;
671 int FileDV::read_compressed_frame(VFrame *buffer)
673         int64_t result;
674         if(stream == 0) return 0;
676         if (fseeko(stream, (off_t) video_position * output_size, SEEK_SET))
677         {
678                 fprintf(stderr, "FileDV::read_compressed_frame: Unable to seek file to %lli\n", (off_t)(video_position * output_size));
679         }
680         result = fread(buffer->get_data(), output_size, 1, stream);
681         video_position++;
683         buffer->set_compressed_size(result);
684         
685         return result != 0;
688 int FileDV::write_compressed_frame(VFrame *buffer)
690         int result = 0;
691         if(stream == 0) return 0;
693         if (fseeko(stream, (off_t) video_position * output_size, SEEK_SET))
694         {
695                 fprintf(stderr, "FileDV::read_compressed_frame: Unable to seek file to %lli", (off_t)(video_position * output_size));
696         }
697         result = fwrite(buffer->get_data(), buffer->get_compressed_size(), 1, stream);
698         video_position++;
699         return result != 0;
702 int64_t FileDV::compressed_frame_size()
704         return output_size;
707 int FileDV::read_samples(double *buffer, int64_t len)
709         int count = 0;
710         int result = 0;
711         int frame_count = get_audio_frame(audio_position);
712         int offset = get_audio_offset(audio_position);
713         
714         stream_lock->lock("FileDV::read_samples");
715         if(stream == 0)
716         {
717                 stream_lock->unlock();
718                 return 1;
719         }
720         stream_lock->unlock();
722         // If the sample rate is 32 kHz, and the bitsize is 12, libdv
723         // requires we have space allocated for 4 channels even if
724         // the data only contains two channels.
726         // decoder will exist since it is not free'd after open_file
727         int channels = (asset->sample_rate == 32000 && decoder->audio->quantization == 12) ? 4 : 2;
729         int16_t **out_buffer = new int16_t*[channels];
730         for(int i = 0; i < channels; i++)
731                 out_buffer[i] = new int16_t[DV_AUDIO_MAX_SAMPLES];
733         while(count < len)
734         {
735                 stream_lock->lock();
736                 
737                 if(fseeko(stream, (off_t) frame_count * output_size, SEEK_SET) != 0)
738                 {
739                         stream_lock->unlock();
740                         result = 1;
741                         break;
742                 }
743                 
744                 if(fread(audio_buffer, output_size, 1, stream) < 1)
745                 {
746                         stream_lock->unlock();
747                         result = 1;
748                         break;
749                 }
751                 stream_lock->unlock();
752                 
753                 frame_count++;
754                 
755                 decoder_lock->lock("FileDV::read_samples");
756                 
757                 if(dv_decode_full_audio(decoder, audio_buffer, out_buffer) < 0)
758                 {
759                         fprintf(stderr, "Error decoding audio frame %d\n", frame_count - 1);
760                 }
762                 int end = dv_get_num_samples(decoder);
763                 decoder_lock->unlock();
765                 if(len - count + offset < end)
766                         end = len - count + offset;
768                 for(int i = offset; i < end; i++)
769                         buffer[count++] = out_buffer[file->current_channel][i] / 32767.0;
771                 offset = 0;
772         }
773         
774         for(int i = 0; i < channels; i++)
775                 delete[] out_buffer[i];
776         delete[] out_buffer;
778         audio_position += len;
779         
780         return result;
783 int FileDV::read_frame(VFrame *frame)
785         if(stream == 0) return 1;
786         int pitches[3] = {720 * 2, 0, 0};
788 TRACE("FileDV::read_frame 1")
789         unsigned char **row_pointers = frame->get_rows();
792 TRACE("FileDV::read_frame 10")
794         // Seek to video position
795         stream_lock->lock("FileDV::read_frame");
796         if(fseeko(stream, (off_t) video_position * output_size, SEEK_SET) < 0)
797         {
798                 fprintf(stderr, "FileDV::read_frame: Unable to seek file to %lli", (off_t)(video_position * output_size));
799                 stream_lock->unlock();
800                 return 1;
801         }
802         fread(video_buffer, output_size, 1, stream);
803         stream_lock->unlock();
804         video_position++;
805         
807 TRACE("FileDV::read_frame 20")
809         switch(frame->get_color_model())
810         {
811                 case BC_COMPRESSED:
813 TRACE("FileDV::read_frame 30")
815                         frame->allocate_compressed_data(output_size);
816                         frame->set_compressed_size(output_size);
817                         memcpy(frame->get_data(), video_buffer, output_size);
818                         break;
819                 case BC_RGB888:
821 TRACE("FileDV::read_frame 40")
823                         pitches[0] = 720 * 3;
824                         decoder_lock->lock("FileDV::read_frame 10");
825                         dv_decode_full_frame(decoder, video_buffer, e_dv_color_rgb,
826                                 row_pointers, pitches);
827                         decoder_lock->unlock();
828                         break;
829                 case BC_YUV422:
830 TRACE("FileDV::read_frame 50")
831                         decoder_lock->lock("FileDV::read_frame 20");
832                         dv_decode_full_frame(decoder, video_buffer, e_dv_color_yuv,
833                                 row_pointers, pitches);
834                         decoder_lock->unlock();
835                         break;
837                 default:
838                         unsigned char *data = new unsigned char[asset->height * asset->width * 2];
839                         unsigned char **temp_pointers = new unsigned char*[asset->height];
841                         for(int i = 0; i < asset->height; i++)
842                                 temp_pointers[i] = data + asset->width * 2 * i;
843                                 
844                         
845 TRACE("FileDV::read_frame 69")
847                         decoder_lock->lock("FileDV::read_frame 30");
848                         dv_decode_full_frame(decoder, video_buffer, e_dv_color_yuv,
849                                 temp_pointers, pitches);
850                         decoder_lock->unlock();
852 TRACE("FileDV::read_frame 70")
854                         cmodel_transfer(row_pointers,
855                                 temp_pointers,
856                                 row_pointers[0],
857                                 row_pointers[1],
858                                 row_pointers[2],
859                                 temp_pointers[0],
860                                 temp_pointers[1],
861                                 temp_pointers[2],
862                                 0,
863                                 0,
864                                 asset->width,
865                                 asset->height,
866                                 0,
867                                 0,
868                                 asset->width,
869                                 asset->height,
870                                 BC_YUV422,
871                                 frame->get_color_model(),
872                                 0,
873                                 asset->width,
874                                 asset->width);
875                         
876                         //for(int i = 0; i < asset->height; i++)
877                         //      delete[] temp_pointers[i];
878                         delete[] temp_pointers;
879                         delete[] data;
881                         
882                         break;
883         }
885 TRACE("FileDV::read_frame 80")
887 UNTRACE
889         return 0;       
892 int FileDV::colormodel_supported(int colormodel)
894         return colormodel;
897 int FileDV::can_copy_from(Edit *edit, int64_t position)
899         if(edit->asset->format == FILE_RAWDV ||
900                         (edit->asset->format == FILE_MOV &&
901                                 (match4(edit->asset->vcodec, QUICKTIME_DV) ||
902                                 match4(edit->asset->vcodec, QUICKTIME_DVSD))))
903                 return 1;
905         return 0;
908 int FileDV::get_best_colormodel(Asset *asset, int driver)
910         switch(driver)
911         {
912                 case PLAYBACK_X11:
913                         return BC_RGB888;
914                         break;
915                 case PLAYBACK_X11_XV:
916                         return BC_YUV422;
917                         break;
918                 case PLAYBACK_DV1394:
919                 case PLAYBACK_FIREWIRE:
920                         return BC_COMPRESSED;
921                         break;
922                 case PLAYBACK_LML:
923                 case PLAYBACK_BUZ:
924                         return BC_YUV422P;
925                         break;
926                 case VIDEO4LINUX:
927                 case VIDEO4LINUX2:
928                 case CAPTURE_BUZ:
929                 case CAPTURE_LML:
930                 case VIDEO4LINUX2JPEG:
931                         return BC_YUV422;
932                         break;
933                 case CAPTURE_FIREWIRE:
934                         return BC_COMPRESSED;
935                         break;
936         }
937         return BC_RGB888;
940 int FileDV::get_audio_frame(int64_t pos)
942         return (double) pos * asset->frame_rate / asset->sample_rate;
945 // Get the sample offset from the frame start reported by get_audio_frame
946 int FileDV::get_audio_offset(int64_t pos)
948         int frame = get_audio_frame(pos);
949                 
950         // Samples needed from last frame
951         return  pos - frame * asset->sample_rate / asset->frame_rate;
974 DVConfigAudio::DVConfigAudio(BC_WindowBase *parent_window, Asset *asset)
975  : BC_Window(PROGRAM_NAME ": Audio Compression",
976         parent_window->get_abs_cursor_x(1),
977         parent_window->get_abs_cursor_y(1),
978         350,
979         250)
981         this->parent_window = parent_window;
982         this->asset = asset;
985 DVConfigAudio::~DVConfigAudio()
990 int DVConfigAudio::create_objects()
992         add_tool(new BC_Title(10, 10, _("There are no audio options for this format")));
993         add_subwindow(new BC_OKButton(this));
994         return 0;
997 int DVConfigAudio::close_event()
999         set_done(0);
1000         return 1;
1008 DVConfigVideo::DVConfigVideo(BC_WindowBase *parent_window, Asset *asset)
1009  : BC_Window(PROGRAM_NAME ": Video Compression",
1010         parent_window->get_abs_cursor_x(1),
1011         parent_window->get_abs_cursor_y(1),
1012         350,
1013         250)
1015         this->parent_window = parent_window;
1016         this->asset = asset;
1019 DVConfigVideo::~DVConfigVideo()
1024 int DVConfigVideo::create_objects()
1026         add_tool(new BC_Title(10, 10, _("There are no video options for this format")));
1027         add_subwindow(new BC_OKButton(this));
1028         return 0;
1031 int DVConfigVideo::close_event()
1033         set_done(0);
1034         return 1;