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