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