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