9 #include "interlacemodes.h"
11 #include "mwindow.inc"
12 #include "quicktime.h"
14 #include "videodevice.inc"
15 #include "cmodel_permutation.h"
17 #include <sys/types.h>
26 FileDV::FileDV(Asset *asset, File *file)
27 : FileBase(asset, file)
39 audio_sample_buffer = 0;
40 audio_sample_buffer_len = 0;
41 audio_sample_buffer_start = 0;
42 audio_sample_buffer_end = 0;
43 audio_sample_buffer_maxsize = 0;
45 audio_frames_written = 0;
47 if(asset->format == FILE_UNKNOWN)
48 asset->format = FILE_RAWDV;
49 asset->byte_order = 0;
51 stream_lock = new Mutex("FileDV::stream_lock");
52 decoder_lock = new Mutex("FileDV::decoder_lock");
53 video_position_lock = new Mutex("FileDV::video_position_lock");
58 if(stream) close_file();
60 if(decoder) dv_decoder_free(decoder);
61 if(encoder) dv_encoder_free(encoder);
62 if(audio_encoder) dv_encoder_free(audio_encoder);
66 delete video_position_lock;
68 delete[] video_buffer;
69 delete[] audio_buffer;
71 if(audio_sample_buffer)
73 for(int i = 0; i < asset->channels; i++)
74 delete[] audio_sample_buffer[i];
75 delete[] audio_sample_buffer;
79 void FileDV::get_parameters(BC_WindowBase *parent_window,
81 BC_WindowBase* &format_window,
87 DVConfigAudio *window = new DVConfigAudio(parent_window, asset);
88 format_window = window;
89 window->create_objects();
96 DVConfigVideo *window = new DVConfigVideo(parent_window, asset);
97 format_window = window;
98 window->create_objects();
105 int FileDV::reset_parameters_derived()
107 if(decoder) dv_decoder_free(decoder);
108 if(encoder) dv_encoder_free(encoder);
109 if(audio_encoder) dv_encoder_free(audio_encoder);
114 TRACE("FileDV::reset_parameters_derived 10")
116 TRACE("FileDV::reset_parameters_derived: 20")
117 delete[] audio_buffer;
118 delete[] video_buffer;
119 TRACE("FileDV::reset_parameters_derived: 30")
124 if(stream) fclose(stream);
131 if(audio_sample_buffer)
133 for(int i = 0; i < asset->channels; i++)
134 delete[] audio_sample_buffer[i];
135 delete[] audio_sample_buffer;
137 audio_sample_buffer = 0;
138 audio_sample_buffer_start = 0;
139 audio_sample_buffer_len = 0;
140 audio_sample_buffer_end = 0;
141 audio_sample_buffer_maxsize = 0;
143 audio_frames_written = 0;
144 // output_size gets set in open_file, once we know if the frames are PAL or NTSC
145 // output and input are allocated at the same point.
152 int FileDV::open_file(int rd, int wr)
155 TRACE("FileDV::open_file 10")
160 TRACE("FileDV::open_file 20")
163 if (!(asset->height == 576 && asset->width == 720 && asset->frame_rate == 25) &&
164 !(asset->height == 480 && asset->width == 720 && (asset->frame_rate >= 29.96 && asset->frame_rate <= 29.98)))
166 printf("Resolution not supported for dv: %ix%i framerate: %f\n", asset->width, asset->height, asset->frame_rate);
167 if (asset->height == 480 && asset->width == 720 && asset->frame_rate == 30)
169 printf("Suggestion: Proper frame rate for NTSC DV is 29.97\n");
173 if (!(asset->channels == 2 && (asset->sample_rate == 48000 || asset->sample_rate == 44100)) &&
174 !((asset->channels == 4 || asset->channels == 2) && asset->sample_rate == 32000))
176 printf("Audio configuration not supported for dv: channels: %i, sample rate: %i\n", asset->channels, asset->sample_rate);
184 if((stream = fopen(asset->path, "w+b")) == 0)
186 perror(_("FileDV::open_file rdwr"));
190 // Create a new encoder
191 if(encoder) dv_encoder_free(encoder);
192 encoder = dv_encoder_new(0,0,0);
193 encoder->vlc_encode_passes = 3;
194 encoder->static_qno = 0;
195 encoder->force_dct = DV_DCT_AUTO;
197 if(audio_encoder) dv_encoder_free(audio_encoder);
198 audio_encoder = dv_encoder_new(0, 0, 0);
199 audio_encoder->vlc_encode_passes = 3;
200 audio_encoder->static_qno = 0;
201 audio_encoder->force_dct = DV_DCT_AUTO;
203 if(decoder) dv_decoder_free(decoder);
204 decoder = dv_decoder_new(0,0,0);
205 decoder->quality = DV_QUALITY_BEST;
208 isPAL = (asset->height == 576 ? 1 : 0);
209 encoder->isPAL = isPAL;
210 output_size = (isPAL ? DV1394_PAL_FRAME_SIZE : DV1394_NTSC_FRAME_SIZE);
212 // Compare to 16 / 8 rather than == 16 / 9 in case of floating point
214 encoder->is16x9 = asset->aspect_ratio > 16 / 8;
220 TRACE("FileDV::open_file 30")
224 TRACE("FileDV::open_file 40")
226 if((stream = fopen(asset->path, "rb")) == 0)
228 perror(_("FileDV::open_file rd"));
232 // temp storage to find out the correct info from the stream.
233 temp = new unsigned char[DV1394_PAL_FRAME_SIZE];
234 memset(temp, 0, DV1394_PAL_FRAME_SIZE);
236 // need file size info to get length.
237 stat(asset->path, &info);
239 TRACE("FileDV::open_file 50")
241 // read the first frame so we can get the stream info from it
242 // by reading the greatest possible frame size, we ensure we get all the
243 // data. libdv will determine if it's PAL or NTSC, and input and output
244 // buffers get allocated accordingly.
245 fread(temp, DV1394_PAL_FRAME_SIZE, 1, stream);
247 TRACE("FileDV::open_file 60")
249 if(decoder) dv_decoder_free(decoder);
250 decoder = dv_decoder_new(0,0,0);
251 decoder->quality = DV_QUALITY_BEST;
254 if(dv_parse_header(decoder, temp) > -1 )
256 // define video params first -- we need to find out output_size
258 asset->video_data = 1;
261 //TODO: according to the information I found, letterbox and widescreen
262 //are the same thing; however, libdv provides a function to check
263 //if the video feed is one of the other. Need to find out if there
265 if(dv_format_normal(decoder) != 0) asset->aspect_ratio = (double) 4 / 3;
266 else asset->aspect_ratio = (double) 16 / 9;
268 asset->width = decoder->width;
269 asset->height = decoder->height;
271 if(dv_is_progressive(decoder) > 0)
272 asset->interlace_mode = BC_ILACE_MODE_NOTINTERLACED;
274 asset->interlace_mode = BC_ILACE_MODE_BOTTOM_FIRST;
276 isPAL = dv_is_PAL(decoder);
278 output_size = (isPAL ? DV1394_PAL_FRAME_SIZE : DV1394_NTSC_FRAME_SIZE);
279 asset->video_length = info.st_size / output_size;
281 if(!asset->frame_rate)
282 asset->frame_rate = (isPAL ? 25 : 29.97);
283 strncpy(asset->vcodec, "dvc ", 4);
285 // see if there are any audio tracks
286 asset->channels = dv_get_num_channels(decoder);
287 if(asset->channels > 0)
289 asset->audio_data = 1;
290 asset->sample_rate = dv_get_frequency(decoder);
291 // libdv always scales the quantization up to 16 bits for dv_decode_full_audio
293 asset->audio_length = (int64_t) (info.st_size / output_size / asset->frame_rate * asset->sample_rate);
294 strncpy(asset->acodec, "dvc ", 4);
297 asset->audio_data = 0;
301 asset->audio_data = 0;
302 asset->video_data = 0;
305 fseeko(stream, 0, SEEK_SET);
306 TRACE("FileDV::open_file 80")
311 // allocate space for audio and video
312 video_buffer = new unsigned char[output_size + 4];
313 audio_buffer = new unsigned char[output_size + 4];
319 int FileDV::check_sig(Asset *asset)
321 unsigned char temp[3];
322 FILE *t_stream = fopen(asset->path, "rb");
324 fread(&temp, 3, 1, t_stream);
328 if(temp[0] == 0x1f &&
336 int FileDV::close_file_derived()
338 if(stream) fclose(stream);
344 int64_t FileDV::get_video_position()
346 return video_position;
349 int64_t FileDV::get_audio_position()
351 return audio_position;
354 int FileDV::set_video_position(int64_t x)
360 int FileDV::set_audio_position(int64_t x)
366 int FileDV::audio_samples_copy(double **buffer, int64_t len)
368 // take the buffer and copy it into a queue
369 if(!audio_sample_buffer)
371 audio_sample_buffer = new int16_t*[asset->channels];
372 if(!audio_sample_buffer)
374 fprintf(stderr, "ERROR: Unable to allocate memory for audio_sample_buffer.\n");
378 for(int i = 0; i < asset->channels; i++)
380 audio_sample_buffer[i] = new int16_t[len * 2];
382 if(!audio_sample_buffer[i])
384 fprintf(stderr, "ERROR: Unable to allocate memory for "
385 "audio_sample_buffer channel %d\n", i);
389 audio_sample_buffer_maxsize = len * 2;
390 audio_sample_buffer_len = 0;
391 audio_sample_buffer_start = 0;
392 audio_sample_buffer_end = 0;
395 if(audio_sample_buffer_maxsize <= audio_sample_buffer_len + len)
397 // Allocate double the needed size
398 for(int i = 0; i < asset->channels; i++)
400 int16_t *tmp = new int16_t[(audio_sample_buffer_len + len) * 2];
403 fprintf(stderr, "ERROR: Unable to reallocate memory for "
404 "audio_sample_buffer channel %d\n", i);
407 // Copy everything from audio_sample_buffer into tmp
408 for(int a = 0, b = audio_sample_buffer_start;
409 a < audio_sample_buffer_len;
410 a++, b = (b < (audio_sample_buffer_maxsize - 1) ? (b + 1) : 0))
412 tmp[a] = audio_sample_buffer[i][b];
414 // Free the current buffer, and reassign tmp to audio_sample_buffer[i]
415 delete[] audio_sample_buffer[i];
416 audio_sample_buffer[i] = tmp;
418 audio_sample_buffer_start = 0;
419 audio_sample_buffer_end = audio_sample_buffer_len - 1;
420 audio_sample_buffer_maxsize = (audio_sample_buffer_len + len) * 2;
424 for(int i = 0; i < asset->channels; i++)
426 if(len + audio_sample_buffer_end < audio_sample_buffer_maxsize)
428 // copy buffer into audio_sample_buffer, straight out (no loop around)
429 for(int a = 0; a < len; a++)
431 audio_sample_buffer[i][audio_sample_buffer_end + a] =
432 (buffer[i][a] * 32767);
434 if(i == (asset->channels - 1))
435 audio_sample_buffer_end += len;
439 // Need to loop back to the start of audio_sample_buffer
440 int copy_size = audio_sample_buffer_maxsize - audio_sample_buffer_end;
442 for(int a = 0; a < copy_size; a++)
443 audio_sample_buffer[i][a + audio_sample_buffer_end] =
444 (buffer[i][a] * 32767);
446 for(int a = 0; a < len - copy_size; a++)
447 audio_sample_buffer[i][a] = (buffer[i][a + copy_size] * 32767);
449 if(i == (asset->channels - 1))
450 audio_sample_buffer_end = len - copy_size;
454 audio_sample_buffer_len += len;
459 int FileDV::write_samples(double **buffer, int64_t len)
461 if(audio_samples_copy(buffer, len) != 0)
463 fprintf(stderr, "ERROR: Unable to store sample for FileDV::write_samples\n");
466 video_position_lock->lock("FileDV::write_samples");
468 TRACE("FileDV::write_samples 200")
469 // Get number of frames to be written. Order of operations is important here;
470 // the buffer length must be multiplied by the frame rate first in case the
471 // number of samples in the buffer is less than the sample rate.
472 int nFrames = MIN(video_position - audio_frames_written,
473 audio_sample_buffer_len * asset->frame_rate / asset->sample_rate);
475 video_position_lock->unlock();
477 TRACE("FileDV::write_samples 210")
479 int16_t **tmp_buf = new int16_t*[asset->channels];
480 for(int a = 0; a < asset->channels; a++)
481 tmp_buf[a] = new int16_t[asset->sample_rate];
483 TRACE("FileDV::write_samples 220")
485 for(int i = 0; i < nFrames; i++)
487 stream_lock->lock("FileDV::write_samples 10");
488 if(fseeko(stream, (off_t) audio_frames_written * output_size, SEEK_SET) != 0)
490 fprintf(stderr, "ERROR: Unable to set audio write position to %lli\n", (off_t) audio_frames_written * output_size);
491 stream_lock->unlock();
495 if(fread(audio_buffer, output_size, 1, stream) != 1)
497 fprintf(stderr, "ERROR: Unable to read from file\n");
498 stream_lock->unlock();
502 stream_lock->unlock();
506 TRACE("FileDV::write_samples 230")
508 int samples = dv_calculate_samples(audio_encoder, asset->sample_rate,
509 audio_frames_written);
511 if(samples > audio_sample_buffer_maxsize - 1 - audio_sample_buffer_start)
513 TRACE("FileDV::write_samples 240")
514 int copy_size = audio_sample_buffer_maxsize - audio_sample_buffer_start - 1;
516 for(int a = 0; a < asset->channels; a++)
518 memcpy(tmp_buf[a], audio_sample_buffer[a] + audio_sample_buffer_start,
520 memcpy(tmp_buf[a] + copy_size, audio_sample_buffer[a],
521 samples - copy_size);
523 TRACE("FileDV::write_samples 250")
524 // Encode the audio into the frame
525 if(dv_encode_full_audio(audio_encoder, tmp_buf, asset->channels,
526 asset->sample_rate, audio_buffer) < 0)
528 fprintf(stderr, "ERROR: unable to encode audio frame %d\n", audio_frames_written);
533 TRACE("FileDV::write_samples 260")
534 int16_t **tmp_buf2 = new int16_t*[asset->channels];
535 for(int a = 0; a < asset->channels; a++)
536 tmp_buf2[a] = audio_sample_buffer[a] + audio_sample_buffer_start;
537 if(dv_encode_full_audio(audio_encoder, tmp_buf2,
538 asset->channels, asset->sample_rate, audio_buffer) < 0)
540 fprintf(stderr, "ERROR: unable to encode audio frame %d\n", audio_frames_written);
545 TRACE("FileDV::write_samples 270")
547 stream_lock->lock("FileDV::write_samples 20");
548 if(fseeko(stream, (off_t) audio_frames_written * output_size, SEEK_SET) != 0)
550 fprintf(stderr, "ERROR: Unable to relocate for audio write to %lli\n", (off_t) audio_frames_written * output_size);
551 stream_lock->unlock();
555 if(fwrite(audio_buffer, output_size, 1, stream) != 1)
557 fprintf(stderr, "ERROR: Unable to write audio\n");
558 stream_lock->unlock();
562 stream_lock->unlock();
564 audio_frames_written++;
565 audio_sample_buffer_len -= samples;
566 audio_sample_buffer_start += samples;
567 if(audio_sample_buffer_start >= audio_sample_buffer_maxsize)
568 audio_sample_buffer_start -= audio_sample_buffer_maxsize;
571 TRACE("FileDV::write_samples 280")
573 for(int a = 0; a < asset->channels; a++)
577 TRACE("FileDV::write_samples 290")
585 int FileDV::write_frames(VFrame ***frames, int len)
589 if(stream == 0) return 1;
591 for(int j = 0; j < len && !result; j++)
593 VFrame *temp_frame = frames[0][j];
595 //printf("FileDV::write_frames: color_model %i\n", temp_frame->get_color_model());
596 switch(temp_frame->get_color_model())
599 memcpy(video_buffer, temp_frame->get_data(), output_size);
602 //printf("FileDV::write_frames: 4\n");
603 dv_encode_full_frame(encoder, temp_frame->get_rows(),
604 e_dv_color_yuv, video_buffer);
607 //printf("FileDV::write_frames: 5\n");
608 dv_encode_full_frame(encoder, temp_frame->get_rows(),
609 e_dv_color_rgb, video_buffer);
612 unsigned char *data = new unsigned char[asset->height * asset->width * 2];
613 unsigned char **cmodel_buf = new unsigned char *[asset->height];
614 //printf("FileDV::write_frames: 6\n");
615 unsigned char **row_pointers = temp_frame->get_rows();
616 for(int i = 0; i < asset->height; i++)
617 cmodel_buf[i] = data + asset->width * 2 * i;
619 cmodel_transfer(cmodel_buf,
635 temp_frame->get_color_model(),
641 dv_encode_full_frame(encoder, cmodel_buf,
642 e_dv_color_yuv, video_buffer);
648 //printf("FileDV::write_frames: 7\n");
650 // This is the only thread that modifies video_position,
651 // so video_position_lock can remain unlocked for reads.
652 stream_lock->lock("FileDV::write_frames");
653 if(fseeko(stream, (off_t) video_position * output_size, SEEK_SET) != 0)
655 fprintf(stderr, "FileDV::write_frames: Unable to seek file to %lli\n", (off_t)(video_position * output_size));
657 if(fwrite(video_buffer, output_size, 1, stream) < 1)
659 fprintf(stderr, "FileDV::write_frames: Unable to write video data.\n");
661 stream_lock->unlock();
663 video_position_lock->lock();
665 video_position_lock->unlock();
671 int FileDV::read_compressed_frame(VFrame *buffer)
674 if(stream == 0) return 0;
676 if (fseeko(stream, (off_t) video_position * output_size, SEEK_SET))
678 fprintf(stderr, "FileDV::read_compressed_frame: Unable to seek file to %lli\n", (off_t)(video_position * output_size));
680 result = fread(buffer->get_data(), output_size, 1, stream);
683 buffer->set_compressed_size(result);
688 int FileDV::write_compressed_frame(VFrame *buffer)
691 if(stream == 0) return 0;
693 if (fseeko(stream, (off_t) video_position * output_size, SEEK_SET))
695 fprintf(stderr, "FileDV::read_compressed_frame: Unable to seek file to %lli", (off_t)(video_position * output_size));
697 result = fwrite(buffer->get_data(), buffer->get_compressed_size(), 1, stream);
702 int64_t FileDV::compressed_frame_size()
707 int FileDV::read_samples(double *buffer, int64_t len)
711 int frame_count = get_audio_frame(audio_position);
712 int offset = get_audio_offset(audio_position);
714 stream_lock->lock("FileDV::read_samples");
717 stream_lock->unlock();
720 stream_lock->unlock();
722 // If the sample rate is 32 kHz, and the bitsize is 12, libdv
723 // requires we have space allocated for 4 channels even if
724 // the data only contains two channels.
726 // decoder will exist since it is not free'd after open_file
727 int channels = (asset->sample_rate == 32000 && decoder->audio->quantization == 12) ? 4 : 2;
729 int16_t **out_buffer = new int16_t*[channels];
730 for(int i = 0; i < channels; i++)
731 out_buffer[i] = new int16_t[DV_AUDIO_MAX_SAMPLES];
737 if(fseeko(stream, (off_t) frame_count * output_size, SEEK_SET) != 0)
739 stream_lock->unlock();
744 if(fread(audio_buffer, output_size, 1, stream) < 1)
746 stream_lock->unlock();
751 stream_lock->unlock();
755 decoder_lock->lock("FileDV::read_samples");
757 if(dv_decode_full_audio(decoder, audio_buffer, out_buffer) < 0)
759 fprintf(stderr, "Error decoding audio frame %d\n", frame_count - 1);
762 int end = dv_get_num_samples(decoder);
763 decoder_lock->unlock();
765 if(len - count + offset < end)
766 end = len - count + offset;
768 for(int i = offset; i < end; i++)
769 buffer[count++] = out_buffer[file->current_channel][i] / 32767.0;
774 for(int i = 0; i < channels; i++)
775 delete[] out_buffer[i];
778 audio_position += len;
783 int FileDV::read_frame(VFrame *frame)
785 if(stream == 0) return 1;
786 int pitches[3] = {720 * 2, 0, 0};
788 TRACE("FileDV::read_frame 1")
789 unsigned char **row_pointers = frame->get_rows();
792 TRACE("FileDV::read_frame 10")
794 // Seek to video position
795 stream_lock->lock("FileDV::read_frame");
796 if(fseeko(stream, (off_t) video_position * output_size, SEEK_SET) < 0)
798 fprintf(stderr, "FileDV::read_frame: Unable to seek file to %lli", (off_t)(video_position * output_size));
799 stream_lock->unlock();
802 fread(video_buffer, output_size, 1, stream);
803 stream_lock->unlock();
807 TRACE("FileDV::read_frame 20")
809 switch(frame->get_color_model())
813 TRACE("FileDV::read_frame 30")
815 frame->allocate_compressed_data(output_size);
816 frame->set_compressed_size(output_size);
817 memcpy(frame->get_data(), video_buffer, output_size);
821 TRACE("FileDV::read_frame 40")
823 pitches[0] = 720 * 3;
824 decoder_lock->lock("FileDV::read_frame 10");
825 dv_decode_full_frame(decoder, video_buffer, e_dv_color_rgb,
826 row_pointers, pitches);
827 decoder_lock->unlock();
830 TRACE("FileDV::read_frame 50")
831 decoder_lock->lock("FileDV::read_frame 20");
832 dv_decode_full_frame(decoder, video_buffer, e_dv_color_yuv,
833 row_pointers, pitches);
834 decoder_lock->unlock();
838 unsigned char *data = new unsigned char[asset->height * asset->width * 2];
839 unsigned char **temp_pointers = new unsigned char*[asset->height];
841 for(int i = 0; i < asset->height; i++)
842 temp_pointers[i] = data + asset->width * 2 * i;
845 TRACE("FileDV::read_frame 69")
847 decoder_lock->lock("FileDV::read_frame 30");
848 dv_decode_full_frame(decoder, video_buffer, e_dv_color_yuv,
849 temp_pointers, pitches);
850 decoder_lock->unlock();
852 TRACE("FileDV::read_frame 70")
854 cmodel_transfer(row_pointers,
871 frame->get_color_model(),
876 //for(int i = 0; i < asset->height; i++)
877 // delete[] temp_pointers[i];
878 delete[] temp_pointers;
885 TRACE("FileDV::read_frame 80")
892 int FileDV::colormodel_supported(int colormodel)
897 int FileDV::can_copy_from(Edit *edit, int64_t position)
899 if(edit->asset->format == FILE_RAWDV ||
900 (edit->asset->format == FILE_MOV &&
901 (match4(edit->asset->vcodec, QUICKTIME_DV) ||
902 match4(edit->asset->vcodec, QUICKTIME_DVSD))))
908 int FileDV::get_best_colormodel(Asset *asset, int driver)
915 case PLAYBACK_X11_XV:
918 case PLAYBACK_DV1394:
919 case PLAYBACK_FIREWIRE:
920 return BC_COMPRESSED;
930 case VIDEO4LINUX2JPEG:
933 case CAPTURE_FIREWIRE:
934 return BC_COMPRESSED;
940 int FileDV::get_audio_frame(int64_t pos)
942 return (double) pos * asset->frame_rate / asset->sample_rate;
945 // Get the sample offset from the frame start reported by get_audio_frame
946 int FileDV::get_audio_offset(int64_t pos)
948 int frame = get_audio_frame(pos);
950 // Samples needed from last frame
951 return pos - frame * asset->sample_rate / asset->frame_rate;
974 DVConfigAudio::DVConfigAudio(BC_WindowBase *parent_window, Asset *asset)
975 : BC_Window(PROGRAM_NAME ": Audio Compression",
976 parent_window->get_abs_cursor_x(1),
977 parent_window->get_abs_cursor_y(1),
981 this->parent_window = parent_window;
985 DVConfigAudio::~DVConfigAudio()
990 int DVConfigAudio::create_objects()
992 add_tool(new BC_Title(10, 10, _("There are no audio options for this format")));
993 add_subwindow(new BC_OKButton(this));
997 int DVConfigAudio::close_event()
1008 DVConfigVideo::DVConfigVideo(BC_WindowBase *parent_window, Asset *asset)
1009 : BC_Window(PROGRAM_NAME ": Video Compression",
1010 parent_window->get_abs_cursor_x(1),
1011 parent_window->get_abs_cursor_y(1),
1015 this->parent_window = parent_window;
1016 this->asset = asset;
1019 DVConfigVideo::~DVConfigVideo()
1024 int DVConfigVideo::create_objects()
1026 add_tool(new BC_Title(10, 10, _("There are no video options for this format")));
1027 add_subwindow(new BC_OKButton(this));
1031 int DVConfigVideo::close_event()