11 #include "interlacemodes.h"
13 #include "mwindow.inc"
14 #include "quicktime.h"
16 #include "videodevice.inc"
17 #include "cmodel_permutation.h"
19 #include <sys/types.h>
26 FileDV::FileDV(Asset *asset, File *file)
27 : FileBase(asset, file)
31 avcodec_register_all();
35 #endif // DV_USE_FFMPEG
42 if(asset->format == FILE_UNKNOWN)
43 asset->format = FILE_RAWDV;
44 asset->byte_order = 0;
52 if(stream) close_file();
57 avcodec_close(context);
60 if(picture) free(picture);
61 #endif // DV_USE_FFMPEG
63 if(decoder) dv_decoder_free(decoder);
64 if(encoder) dv_encoder_free(encoder);
67 for(i = 0; i < asset->channels; i++)
68 free(audio_buffer[i]);
75 void FileDV::get_parameters(BC_WindowBase *parent_window,
77 BC_WindowBase* &format_window,
83 DVConfigAudio *window = new DVConfigAudio(parent_window, asset);
84 format_window = window;
85 window->create_objects();
92 DVConfigVideo *window = new DVConfigVideo(parent_window, asset);
93 format_window = window;
94 window->create_objects();
101 int FileDV::reset_parameters_derived()
108 avcodec_close(context);
113 if(picture) free(picture);
115 #endif // DV_USE_FFMPEG
117 if(decoder) dv_decoder_free(decoder);
118 if(encoder) dv_encoder_free(encoder);
120 TRACE("FileDV::reset_parameters_derived 10")
123 codec = avcodec_find_decoder(CODEC_ID_DVVIDEO);
124 context = avcodec_alloc_context();
125 avcodec_open(context, codec);
126 #endif // DV_USE_FFMPEG
128 decoder = dv_decoder_new(0,0,0);
129 decoder->quality = DV_QUALITY_BEST;
130 encoder = dv_encoder_new(0,0,0);
131 encoder->vlc_encode_passes = 3;
132 encoder->static_qno = 0;
133 encoder->force_dct = DV_DCT_AUTO;
135 TRACE("FileDV::reset_parameters_derived: 20")
139 for(i = 0; i < asset->channels; i++)
141 if(audio_buffer[i]) free(audio_buffer[i]);
146 TRACE("FileDV::reset_parameters_derived: 30")
149 samples_in_buffer = 0;
150 for(i = 0; i < 4; i++) // max 4 channels in dv
151 samples_offset[i] = 0;
158 // output_size gets set in open_file, once we know if the frames are PAL or NTSC
159 // output and input are allocated at the same point.
165 current_frame = asset->tcstart;
171 int FileDV::open_file(int rd, int wr)
174 TRACE("FileDV::open_file 10")
179 TRACE("FileDV::open_file 20")
181 if((stream = fopen(asset->path, "w+b")) == 0)
183 perror(_("FileDV::open_file rdwr"));
187 isPAL = (asset->height == 576 ? 1 : 0);
188 encoder->isPAL = isPAL;
189 output_size = (isPAL ? DV1394_PAL_FRAME_SIZE : DV1394_NTSC_FRAME_SIZE);
195 TRACE("FileDV::open_file 30")
199 TRACE("FileDV::open_file 40")
201 if((stream = fopen(asset->path, "rb")) == 0)
203 perror(_("FileDV::open_file rd"));
207 // temp storage to find out the correct info from the stream.
208 temp = new unsigned char[DV1394_PAL_FRAME_SIZE + 8];
209 memset(temp, 0, DV1394_PAL_FRAME_SIZE + 8);
211 // need file size info to get length.
212 info = (struct stat*) malloc(sizeof(struct stat));
213 stat(asset->path, info);
215 TRACE("FileDV::open_file 50")
217 // read the first frame so we can get the stream info from it
218 // by reading the greatest possible frame size, we ensure we get all the
219 // data. libdv will determine if it's PAL or NTSC, and input and output
220 // buffers get allocated accordingly.
221 fread(temp, DV1394_PAL_FRAME_SIZE, 1, stream);
223 TRACE("FileDV::open_file 60")
225 if(dv_parse_header(decoder, temp) > -1 )
229 // define video params first -- we need to find out output_size
231 asset->video_data = 1;
233 asset->aspect_ratio = (double) 4 / 3;
234 asset->width = decoder->width;
235 asset->height = decoder->height;
236 asset->interlace_mode = BC_ILACE_MODE_UNDETECTED; // FIXME: Is this set to a standard??
237 if(asset->height == 576)
242 output_size = (isPAL ? DV1394_PAL_FRAME_SIZE : DV1394_NTSC_FRAME_SIZE);
243 asset->video_length = info->st_size / output_size;
244 if(!asset->frame_rate)
245 asset->frame_rate = (isPAL ? 25 : 29.97);
246 strncpy(asset->vcodec, "dvc ", 4);
248 // see if there are any audio tracks
249 asset->channels = decoder->audio->num_channels;
250 if(asset->channels > 0)
252 asset->audio_data = 1;
253 asset->sample_rate = decoder->audio->frequency;
254 asset->bits = decoder->audio->quantization;
255 asset->audio_length = info->st_size * decoder->audio->samples_this_frame / output_size;
256 strncpy(asset->acodec, "dvc ", 4);
259 asset->audio_data = 0;
261 // Set start timecode
262 dv_parse_packs(decoder, temp);
263 dv_get_timestamp(decoder, tc);
264 asset->set_timecode(tc, TC_DROPFRAME, 0);
266 // Get the last frame's timecode
267 set_video_position(asset->video_length);
268 fread(temp, DV1394_PAL_FRAME_SIZE, 1, stream);
269 dv_parse_header(decoder, temp);
270 dv_parse_packs(decoder, temp);
271 dv_get_timestamp(decoder, tc);
273 asset->set_timecode(tc, TC_DROPFRAME, 1);
277 asset->audio_data = 0;
278 asset->video_data = 0;
281 fseek(stream, 0, SEEK_SET);
282 TRACE("FileDV::open_file 80")
290 /// allocate space for input and output
291 input = new unsigned char[output_size + 8];
292 output = new unsigned char[output_size + 8];
293 memset(input, 0, output_size + 8);
294 memset(output, 0, output_size + 8);
300 int FileDV::check_sig(Asset *asset)
302 unsigned char temp[3];
303 FILE *t_stream = fopen(asset->path, "rb");
305 fread(&temp, 3, 1, t_stream);
309 if(temp[0] == 0x1f &&
317 int FileDV::close_file()
323 int FileDV::close_file_derived()
325 //printf("FileDV::close_file_derived(): 1\n");
330 int64_t FileDV::get_video_position()
332 return video_offset / output_size;
335 int64_t FileDV::get_audio_position()
337 return audio_position;
340 int FileDV::set_video_position(int64_t x)
342 if(!stream) return 1;
343 if(x >= 0 && x < asset->video_length)
345 video_offset = x * output_size;
352 int FileDV::set_audio_position(int64_t x)
355 if(!stream) return 1;
356 if(x >= 0 && x < asset->audio_length)
359 audio_offset = output_size * (int64_t) (x / (asset->sample_rate / asset->frame_rate));
360 for(i = 0; i < 4; i++)
362 samples_offset[i] = audio_position - (int) (audio_offset / output_size / asset->frame_rate * asset->sample_rate);
370 int FileDV::write_samples(double **buffer, int64_t len)
372 int frame_num = (int) (audio_offset / output_size);
373 // How many samples do we write this frame?
374 int samples = calculate_samples(frame_num);
375 int samples_written = 0;
377 unsigned char *temp_data = (unsigned char *) calloc(sizeof(unsigned char*), output_size);
378 int16_t *temp_buffers[asset->channels];
380 TRACE("FileDV::write_samples 10")
384 audio_buffer = (int16_t **) calloc(sizeof(int16_t*), asset->channels);
386 // TODO: should reallocate if len > asset->sample_rate * 2, or
387 // len > asset->sample_rate + samples_in_buffer
389 // allocate enough so that we can write two seconds worth of frames (we
390 // usually receive one second of frames to write, and we need
391 // overflow if the frames aren't already written
392 for(i = 0; i < asset->channels; i++)
394 audio_buffer[i] = (int16_t *) calloc(sizeof(int16_t), asset->sample_rate * 2);
398 TRACE("FileDV::write_samples 20")
400 for(i = 0; i < asset->channels; i++)
402 temp_buffers[i] = audio_buffer[i];
403 // Need case handling for bitsize ?
405 TRACE("FileDV::write_samples 22")
407 for(j = 0; j < len; j++)
410 TRACE("FileDV::write_samples 24")
412 if(samples_in_buffer > 0)
413 temp_buffers[i][j + samples_in_buffer - 1] = (int16_t) (buffer[i][j] * 32767);
415 temp_buffers[i][j] = (int16_t) (buffer[i][j] * 32767);
419 samples_in_buffer += len;
421 TRACE("FileDV::write_samples 30")
423 // We can only write the number of frames that write_frames has written
424 // since our last audio write, and we can't write more than the
425 // samples we have available from the last write and this one
426 for(i = 0; i < frames_written && samples_written + samples <= samples_in_buffer; i++)
428 // Position ourselves to where we last wrote audio
429 fseek(stream, audio_offset, SEEK_SET);
431 // Read the frame in, add the audio, write it back out to the same
432 // location and adjust audio_offset to the new file position
433 if(fread(temp_data, output_size, 1, stream) < 1) break;
434 encoder->samples_this_frame = samples;
435 dv_encode_full_audio(encoder, temp_buffers, asset->channels,
436 asset->sample_rate, temp_data);
437 fseek(stream, audio_offset, SEEK_SET);
438 fwrite(temp_data, output_size, 1, stream);
439 audio_offset += output_size;
441 TRACE("FileDV::write_samples 50")
443 // Get the next set of samples for the next frame
444 for(j = 0; j < asset->channels; j++)
445 temp_buffers[j] += samples;
447 TRACE("FileDV::write_samples 60")
449 // increase the number of samples written so we can determine how many
450 // samples to leave in the buffer for the next write
451 samples_written += samples;
453 samples = calculate_samples(frame_num);
456 // Get number of frames we didn't write to
459 if(samples_written < samples_in_buffer)
461 // move the rest of the buffer to the front
463 TRACE("FileDV::write_samples 70")
465 samples_in_buffer -= samples_written;
466 for(i = 0; i < asset->channels; i++)
468 memmove(audio_buffer[i], temp_buffers[i], asset->sample_rate * 2 - samples_written);
473 samples_in_buffer = 0;
476 TRACE("FileDV::write_samples 80")
478 if(temp_data) free(temp_data);
485 int FileDV::write_frames(VFrame ***frames, int len)
487 int i, j, result = 0;
489 if(!stream) return 0;
491 for(j = 0; j < len && !result; j++)
493 VFrame *temp_frame = new VFrame(frames[0][j]->get_data(),
496 frames[0][j]->get_color_model(),
497 frames[0][j]->get_bytes_per_line());
499 unsigned char *frame_buf = (unsigned char *)malloc(asset->height * asset->width * 2);
500 unsigned char **cmodel_buf = (unsigned char **)malloc(sizeof(unsigned char*) * asset->height);
502 for(i = 0; i < asset->height; i++)
503 cmodel_buf[i] = frame_buf + 720 * 2 * i;
505 //printf("FileDV::write_frames: color_model %i\n", temp_frame->get_color_model());
506 switch(temp_frame->get_color_model())
509 memcpy(output, temp_frame->get_data(), output_size);
512 //printf("FileDV::write_frames: 4\n");
513 dv_encode_full_frame(encoder, temp_frame->get_rows(),
514 e_dv_color_yuv, output);
517 //printf("FileDV::write_frames: 5\n");
518 dv_encode_full_frame(encoder, temp_frame->get_rows(),
519 e_dv_color_rgb, output);
522 //printf("FileDV::write_frames: 6\n");
523 unsigned char **row_pointers = temp_frame->get_rows();
524 cmodel_transfer(cmodel_buf,
540 temp_frame->get_color_model(),
546 dv_encode_full_frame(encoder, cmodel_buf,
547 e_dv_color_yuv, output);
550 //printf("FileDV::write_frames: 7\n");
552 fseek(stream, video_offset, SEEK_SET);
553 fwrite(output, output_size, 1, stream);
554 video_offset += output_size;
565 int FileDV::read_compressed_frame(VFrame *buffer)
568 if(!stream) return 0;
570 fseek(stream, video_offset, SEEK_SET);
571 fread(buffer->get_data(), output_size, 1, stream);
572 video_offset += output_size;
574 buffer->set_compressed_size(result);
580 int FileDV::write_compressed_frame(VFrame *buffer)
583 if(!stream) return 0;
585 fseek(stream, video_offset, SEEK_SET);
586 fwrite(buffer->get_data(), buffer->get_compressed_size(), 1, stream);
587 video_offset += output_size;
594 int64_t FileDV::compressed_frame_size()
596 if(!stream) return 0;
600 int FileDV::read_samples(double *buffer, int64_t len)
602 int frameno = audio_offset / output_size;
603 int16_t **outbuf = 0;
604 int16_t **temp_buffer = 0;
606 int channel = file->current_channel;
607 int offset = samples_offset[channel];
609 TRACE("FileDV::read_samples 10")
611 outbuf = (int16_t **) calloc(sizeof(int16_t *), asset->channels);
612 temp_buffer = (int16_t **) calloc(sizeof(int16_t *), asset->channels);
614 TRACE("FileDV::read_samples 20")
616 for(i = 0; i < asset->channels; i++)
618 // need a bit extra, since chances are len is not a multiple of the
619 // samples per frame.
621 TRACE("FileDV::read_samples 30")
623 outbuf[i] = (int16_t *) calloc(sizeof(int16_t), len + 2 * DV_AUDIO_MAX_SAMPLES);
624 temp_buffer[i] = outbuf[i];
627 TRACE("FileDV::read_samples 40")
630 fseek(stream, audio_offset, SEEK_SET);
632 // get audio data and put it in buffer
633 for(i = 0; i < len + calculate_samples(frameno); i += calculate_samples(frameno))
636 TRACE("FileDV::read_samples 50")
638 fread(input, output_size, 1, stream);
639 audio_offset += output_size;
640 dv_decode_full_audio(decoder, input, temp_buffer);
642 TRACE("FileDV::read_samples 60")
644 for(j = 0; j < asset->channels; j++)
645 temp_buffer[j] += calculate_samples(frameno);
650 TRACE("FileDV::read_samples 70")
652 for(i = 0; i < len; i++)
653 buffer[i] = (double) outbuf[channel][i + offset] / 32767;
655 TRACE("FileDV::read_samples 80")
657 samples_offset[channel] = (len + offset) % calculate_samples(frameno);
659 TRACE("FileDV::read_samples 90")
661 // we do this to keep everything in sync. When > 1 channel is being
662 // played, our set_audio_position gets overriden every second time,
663 // which is a Good Thing (tm) since it would otherwise be wrong.
664 set_audio_position(audio_position + len);
666 TRACE("FileDV::read_samples 100")
670 TRACE("FileDV::read_samples 105")
672 for(i = 0; i < asset->channels; i++)
675 TRACE("FileDV::read_samples 110")
684 int FileDV::read_frame(VFrame *frame)
686 if(!stream) return 1;
688 int pitches[3] = {720 * 2, 0, 0};
690 TRACE("FileDV::read_frame 1")
692 unsigned char **row_pointers = frame->get_rows();
694 unsigned char *temp_data = (unsigned char *) malloc(asset->height * asset->width * 2);
695 unsigned char **temp_pointers = (unsigned char **)malloc(sizeof(unsigned char *) * asset->height);
697 TRACE("FileDV::read_frame 10")
699 for(i = 0; i < asset->height; i++)
700 temp_pointers[i] = temp_data + asset->width * 2 * i;
702 // Seek to video position
703 if(fseek(stream, video_offset, SEEK_SET) < 0) return 1;
704 fread(input, output_size, 1, stream);
705 video_offset += output_size;
708 TRACE("FileDV::read_frame 20")
710 switch(frame->get_color_model())
714 TRACE("FileDV::read_frame 30")
716 frame->allocate_compressed_data(output_size);
717 frame->set_compressed_size(output_size);
718 memcpy(frame->get_data(), input, output_size);
720 #ifndef DV_USE_FFMPEG
724 TRACE("FileDV::read_frame 40")
726 pitches[0] = 720 * 3;
727 dv_decode_full_frame(decoder, input, e_dv_color_rgb,
728 row_pointers, pitches);
732 TRACE("FileDV::read_frame 50")
734 dv_decode_full_frame(decoder, input, e_dv_color_yuv,
735 row_pointers, pitches);
738 #endif // DV_USE_FFMPEG
742 TRACE("FileDV::read_frame 60")
747 AVPicture temp_picture;
749 TRACE("FileDV::read_frame 61")
751 temp_picture.linesize[0] = 720 * 2;
752 for(i = 0; i < 4; i++)
753 temp_picture.data[i] = temp_pointers[i];
755 TRACE("FileDV::read_frame 62")
758 picture = avcodec_alloc_frame();
760 TRACE("FileDV::read_frame 63")
762 avcodec_decode_video(context,
768 TRACE("FileDV::read_frame 65")
770 img_convert(&temp_picture,
772 (AVPicture *)picture,
773 (isPAL ? PIX_FMT_YUV420P : PIX_FMT_YUV411P),
779 TRACE("FileDV::read_frame 69")
781 dv_decode_full_frame(decoder, input, e_dv_color_yuv,
782 temp_pointers, pitches);
784 #endif // DV_USE_FFMPEG
786 TRACE("FileDV::read_frame 70")
788 cmodel_transfer(row_pointers,
805 frame->get_color_model(),
812 TRACE("FileDV::read_frame 80")
822 int FileDV::colormodel_supported(int colormodel)
827 int FileDV::can_copy_from(Edit *edit, int64_t position)
829 if(edit->asset->format == FILE_RAWDV ||
830 (edit->asset->format == FILE_MOV &&
831 (match4(edit->asset->vcodec, QUICKTIME_DV) ||
832 match4(edit->asset->vcodec, QUICKTIME_DVSD))))
838 int FileDV::get_best_colormodel(Asset *asset, int driver)
845 case PLAYBACK_X11_XV:
848 case PLAYBACK_DV1394:
849 case PLAYBACK_FIREWIRE:
850 return BC_COMPRESSED;
860 case VIDEO4LINUX2JPEG:
863 case CAPTURE_FIREWIRE:
864 return BC_COMPRESSED;
870 // from libdv's dv_calculate_samples, included here for use with ffmpeg and in
871 // case user's libdv doesn't support calculate_samples (although it should).
872 int FileDV::calculate_samples(int frame_count)
877 samples = asset->sample_rate / 25;
878 switch(asset->sample_rate)
881 if(frame_count % 25 == 0)
894 samples = asset->sample_rate / 30;
895 switch(asset->sample_rate)
898 if(frame_count % 5 != 0)
902 if(frame_count % 300 == 0)
904 else if(frame_count % 30 == 0)
906 else if(frame_count % 2 == 0)
912 if(frame_count % 30 == 0)
914 else if(frame_count % 29 == 0)
916 else if(frame_count % 4 == 2)
947 DVConfigAudio::DVConfigAudio(BC_WindowBase *parent_window, Asset *asset)
948 : BC_Window(PROGRAM_NAME ": Audio Compression",
949 parent_window->get_abs_cursor_x(1),
950 parent_window->get_abs_cursor_y(1),
954 this->parent_window = parent_window;
958 DVConfigAudio::~DVConfigAudio()
963 int DVConfigAudio::create_objects()
965 add_tool(new BC_Title(10, 10, _("There are no audio options for this format")));
966 add_subwindow(new BC_OKButton(this));
970 int DVConfigAudio::close_event()
981 DVConfigVideo::DVConfigVideo(BC_WindowBase *parent_window, Asset *asset)
982 : BC_Window(PROGRAM_NAME ": Video Compression",
983 parent_window->get_abs_cursor_x(1),
984 parent_window->get_abs_cursor_y(1),
988 this->parent_window = parent_window;
992 DVConfigVideo::~DVConfigVideo()
997 int DVConfigVideo::create_objects()
999 add_tool(new BC_Title(10, 10, _("There are no video options for this format")));
1000 add_subwindow(new BC_OKButton(this));
1004 int DVConfigVideo::close_event()