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