motion draw_vectors using VFrame draw_pixel brush
[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 "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                 // Compare to 16 / 8 rather than == 16 / 9 in case of floating point
233                 // rounding errors
234                 encoder->is16x9 = asset->aspect_ratio > 16 / 8;
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
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 VIDEO4LINUX2:
937                 case VIDEO4LINUX2JPEG:
938                         return BC_YUV422;
939                         break;
940                 case CAPTURE_FIREWIRE:
941                         return BC_COMPRESSED;
942                         break;
943         }
944         return BC_RGB888;
945 }
946
947 int FileDV::get_audio_frame(int64_t pos)
948 {
949         return (double) pos * asset->frame_rate / asset->sample_rate;
950 }
951
952 // Get the sample offset from the frame start reported by get_audio_frame
953 int FileDV::get_audio_offset(int64_t pos)
954 {
955         int frame = get_audio_frame(pos);
956
957         // Samples needed from last frame
958         return  pos - frame * asset->sample_rate / asset->frame_rate;
959 }
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981 DVConfigAudio::DVConfigAudio(BC_WindowBase *parent_window, Asset *asset)
982  : BC_Window(_(PROGRAM_NAME ": Audio Compression"),
983         parent_window->get_abs_cursor_x(1),
984         parent_window->get_abs_cursor_y(1),
985         350, 250)
986 {
987         this->parent_window = parent_window;
988         this->asset = asset;
989 }
990
991 DVConfigAudio::~DVConfigAudio()
992 {
993
994 }
995
996 void DVConfigAudio::create_objects()
997 {
998         lock_window("DVConfigAudio::create_objects");
999         add_tool(new BC_Title(10, 10, _("There are no audio options for this format")));
1000         add_subwindow(new BC_OKButton(this));
1001         unlock_window();
1002 }
1003
1004 int DVConfigAudio::close_event()
1005 {
1006         set_done(0);
1007         return 1;
1008 }
1009
1010
1011 DVConfigVideo::DVConfigVideo(BC_WindowBase *parent_window, Asset *asset)
1012  : BC_Window(_(PROGRAM_NAME ": Video Compression"),
1013         parent_window->get_abs_cursor_x(1),
1014         parent_window->get_abs_cursor_y(1),
1015         350, 250)
1016 {
1017         this->parent_window = parent_window;
1018         this->asset = asset;
1019 }
1020
1021 DVConfigVideo::~DVConfigVideo()
1022 {
1023
1024 }
1025
1026 void DVConfigVideo::create_objects()
1027 {
1028         lock_window("DVConfigVideo::create_objects");
1029         add_tool(new BC_Title(10, 10, _("There are no video options for this format")));
1030         add_subwindow(new BC_OKButton(this));
1031         unlock_window();
1032 }
1033
1034 int DVConfigVideo::close_event()
1035 {
1036         set_done(0);
1037         return 1;
1038 }
1039
1040 #endif