3 #include "bcwidgetgrid.h"
13 #include "mwindow.inc"
15 #include "videodevice.inc"
16 #include "mainerror.h"
27 N_("Microsoft MPEG-4")
31 N_("Uncompressed RGB")
32 N_("Uncompressed RGBA")
33 N_("YUV 4:2:0 Planar")
34 N_("Component Y'CbCr 8-bit 4:2:2 (yuv2)")
35 N_("Component Y'CbCr 8-bit 4:2:2 (2vuy)")
36 N_("YUV 4:1:1 Packed")
37 N_("Component Y'CbCr 8-bit 4:4:4")
38 N_("Component Y'CbCrA 8-bit 4:4:4:4")
39 N_("Component Y'CbCr 10-bit 4:4:4")
53 #define DIVX_NAME "MPEG-4"
54 #define HV64_NAME "Dual H.264"
55 #define MP4V_NAME "MPEG-4 Video"
56 #define H264_NAME "H.264"
57 #define H263_NAME "H.263"
58 #define HV60_NAME "Dual MPEG-4"
59 #define DIV3_NAME "Microsoft MPEG-4"
61 #define PNG_NAME "PNG"
62 #define PNGA_NAME "PNG with Alpha"
63 #define RGB_NAME "Uncompressed RGB"
64 #define RGBA_NAME "Uncompressed RGBA"
65 #define YUV420_NAME "YUV 4:2:0 Planar"
66 #define YUV422_NAME "Component Y'CbCr 8-bit 4:2:2 (yuv2)"
67 #define TWOVUY_NAME "Component Y'CbCr 8-bit 4:2:2 (2vuy)"
68 #define YUV411_NAME "YUV 4:1:1 Packed"
69 #define YUV444_NAME "Component Y'CbCr 8-bit 4:4:4"
70 #define YUVA4444_NAME "Component Y'CbCrA 8-bit 4:4:4:4"
71 #define YUV444_10BIT_NAME "Component Y'CbCr 10-bit 4:4:4"
72 #define QTJPEG_NAME "JPEG Photo"
73 #define MJPA_NAME "Motion JPEG A"
75 #define TWOS_NAME "Twos complement"
76 #define RAW_NAME "Unsigned"
77 #define IMA4_NAME "IMA-4"
78 #define ULAW_NAME "U-Law"
79 //#define VORBIS_NAME "Vorbis"
80 #define MP3_NAME "MP3"
81 #define MP4A_NAME "MPEG-4 Audio"
82 #define VORBIS_NAME "OGG Vorbis"
88 FileMOV::FileMOV(Asset_GC asset, File *file)
89 : FileBase(asset, file)
92 if(asset->format == FILE_UNKNOWN)
93 asset->format = FILE_MOV;
94 asset->byte_order = 0;
96 threadframe_lock = new Mutex("FileMOV::threadframe_lock");
104 delete threadframe_lock;
108 void FileMOV::get_parameters(BC_WindowBase *parent_window,
110 BC_WindowBase* &format_window,
113 char *locked_compressor)
118 MOVConfigAudio *window = new MOVConfigAudio(parent_window, asset);
119 format_window = window;
120 window->create_objects();
121 window->run_window();
127 MOVConfigVideo *window = new MOVConfigVideo(parent_window,
130 format_window = window;
131 window->create_objects();
132 window->run_window();
137 void FileMOV::fix_codecs(Asset_GC asset)
139 if(!strcasecmp(asset->vcodec, QUICKTIME_DV) ||
140 !strcasecmp(asset->vcodec, QUICKTIME_DVSD) ||
141 !strcasecmp(asset->vcodec, QUICKTIME_DVCP))
143 // printf("AF: %i, AH: %i, VC: %s\n", asset->format, asset->height, asset->vcodec);
144 if (asset->format == FILE_AVI)
145 strcpy (asset->vcodec, QUICKTIME_DVSD);
146 else if (asset->format == FILE_MOV && asset->height == 576)
147 strcpy (asset->vcodec, QUICKTIME_DVCP);
148 else if (asset->format == FILE_MOV && asset->height == 480)
149 strcpy (asset->vcodec, QUICKTIME_DV);
154 int FileMOV::check_codec_params(Asset_GC asset)
156 if(!strcasecmp(asset->vcodec, QUICKTIME_DV) ||
157 !strcasecmp(asset->vcodec, QUICKTIME_DVSD) ||
158 !strcasecmp(asset->vcodec, QUICKTIME_DVCP))
161 if (!(asset->height == 576 && asset->width == 720) &&
162 !(asset->height == 480 && asset->width == 720))
164 eprintf("DV in Quicktime container does not support following resolution: %ix%i\nAllowed resolutions are 720x576 (PAL) and 720x480 (NTSC)\n", asset->width, asset->height);
171 int FileMOV::check_sig(Asset_GC asset)
173 return quicktime_check_sig(asset->path);
177 int FileMOV::reset_parameters_derived()
181 quicktime_atracks = 0;
182 quicktime_vtracks = 0;
185 frames_correction = 0;
186 samples_correction = 0;
192 // Just create the Quicktime objects since this routine is also called
194 int FileMOV::open_file(int rd, int wr)
200 if(suffix_number == 0) strcpy(prefix_path, asset->path);
202 if(!(fd = quicktime_open(asset->path, rd, wr)))
204 eprintf("Error while opening file \"%s\". \n%m\n", asset->path);
208 quicktime_set_cpus(fd, file->cpus);
210 if(rd) format_to_asset();
215 if (check_codec_params(asset))
218 // Set decoding parameter
219 quicktime_set_parameter(fd, "divx_use_deblocking", &asset->divx_use_deblocking);
221 // Set timecode offset
222 quicktime_set_frame_start(fd, asset->tcstart);
227 int FileMOV::close_file()
229 //printf("FileMOV::close_file 1 %s\n", asset->path);
232 if(wr) quicktime_set_framerate(fd, asset->frame_rate);
236 //printf("FileMOV::close_file 1\n");
239 for(int i = 0; i < file->cpus; i++)
241 threads[i]->stop_encoding();
248 //printf("FileMOV::close_file 1\n");
249 threadframes.remove_all_objects();
254 for(int i = 0; i < asset->channels; i++)
255 delete [] temp_float[i];
256 delete [] temp_float;
259 //printf("FileMOV::close_file 1\n");
261 FileBase::close_file();
262 //printf("FileMOV::close_file 2\n");
266 void FileMOV::set_frame_start(int64_t offset)
268 quicktime_set_frame_start(fd, offset);
271 void FileMOV::asset_to_format()
278 // Fix up the Quicktime file.
279 quicktime_set_copyright(fd, _("Made with Cinelerra for Linux"));
280 quicktime_set_info(fd, "Quicktime for Linux");
282 if(asset->audio_data)
284 quicktime_atracks = quicktime_set_audio(fd,
289 quicktime_set_parameter(fd, "vorbis_vbr", &asset->vorbis_vbr);
290 quicktime_set_parameter(fd, "vorbis_min_bitrate", &asset->vorbis_min_bitrate);
291 quicktime_set_parameter(fd, "vorbis_bitrate", &asset->vorbis_bitrate);
292 quicktime_set_parameter(fd, "vorbis_max_bitrate", &asset->vorbis_max_bitrate);
293 quicktime_set_parameter(fd, "mp3_bitrate", &asset->mp3_bitrate);
294 quicktime_set_parameter(fd, "mp4a_bitrate", &asset->mp4a_bitrate);
297 if(asset->video_data)
300 // Set up the alpha channel compressors
301 if(!strcmp(asset->vcodec, MOV_RGBA))
303 strcpy(string, QUICKTIME_RAW);
307 if(!strcmp(asset->vcodec, MOV_PNGA))
309 strcpy(string, QUICKTIME_PNG);
313 if(!strcmp(asset->vcodec, QUICKTIME_YUVA4444))
315 strcpy(string, asset->vcodec);
320 strcpy(string, asset->vcodec);
325 quicktime_vtracks = quicktime_set_video(fd,
334 for(int i = 0; i < asset->layers; i++)
335 quicktime_set_depth(fd, depth, i);
337 quicktime_set_parameter(fd, "jpeg_quality", &asset->jpeg_quality);
339 // set the compression parameters if there are any
340 quicktime_set_parameter(fd, "divx_bitrate", &asset->divx_bitrate);
341 quicktime_set_parameter(fd, "divx_rc_period", &asset->divx_rc_period);
342 quicktime_set_parameter(fd, "divx_rc_reaction_ratio", &asset->divx_rc_reaction_ratio);
343 quicktime_set_parameter(fd, "divx_rc_reaction_period", &asset->divx_rc_reaction_period);
344 quicktime_set_parameter(fd, "divx_max_key_interval", &asset->divx_max_key_interval);
345 quicktime_set_parameter(fd, "divx_max_quantizer", &asset->divx_max_quantizer);
346 quicktime_set_parameter(fd, "divx_min_quantizer", &asset->divx_min_quantizer);
347 quicktime_set_parameter(fd, "divx_quantizer", &asset->divx_quantizer);
348 quicktime_set_parameter(fd, "divx_quality", &asset->divx_quality);
349 quicktime_set_parameter(fd, "divx_fix_bitrate", &asset->divx_fix_bitrate);
351 quicktime_set_parameter(fd, "ffmpeg_bitrate", &asset->ms_bitrate);
352 quicktime_set_parameter(fd, "ffmpeg_bitrate_tolerance", &asset->ms_bitrate_tolerance);
353 quicktime_set_parameter(fd, "ffmpeg_interlaced", &asset->ms_interlaced);
354 quicktime_set_parameter(fd, "ffmpeg_quantizer", &asset->ms_quantization);
355 quicktime_set_parameter(fd, "ffmpeg_gop_size", &asset->ms_gop_size);
356 quicktime_set_parameter(fd, "ffmpeg_fix_bitrate", &asset->ms_fix_bitrate);
358 quicktime_set_parameter(fd, "h264_bitrate", &asset->h264_bitrate);
359 quicktime_set_parameter(fd, "h264_quantizer", &asset->h264_quantizer);
360 quicktime_set_parameter(fd, "h264_fix_bitrate", &asset->h264_fix_bitrate);
365 if(wr && asset->format == FILE_AVI)
367 quicktime_set_avi(fd, 1);
372 void FileMOV::format_to_asset()
376 if(quicktime_is_avi(fd)) asset->format = FILE_AVI;
377 asset->audio_data = quicktime_has_audio(fd);
378 if(asset->audio_data)
381 int qt_tracks = quicktime_audio_tracks(fd);
382 for(int i = 0; i < qt_tracks; i++)
383 asset->channels += quicktime_track_channels(fd, i);
385 if(!asset->sample_rate)
386 asset->sample_rate = quicktime_sample_rate(fd, 0);
387 asset->bits = quicktime_audio_bits(fd, 0);
388 asset->audio_length = quicktime_audio_length(fd, 0);
389 strncpy(asset->acodec, quicktime_audio_compressor(fd, 0), 4);
392 // determine if the video can be read before declaring video data
393 if(quicktime_has_video(fd) && quicktime_supported_video(fd, 0))
394 asset->video_data = 1;
396 if(asset->video_data)
398 depth = quicktime_video_depth(fd, 0);
399 asset->layers = quicktime_video_tracks(fd);
400 asset->width = quicktime_video_width(fd, 0);
401 asset->height = quicktime_video_height(fd, 0);
402 asset->video_length = quicktime_video_length(fd, 0);
403 // Don't want a user configured frame rate to get destroyed
404 if(!asset->frame_rate)
405 asset->frame_rate = quicktime_frame_rate(fd, 0);
406 if(!asset->interlace_mode)
407 asset->interlace_mode = quicktime_video_interlacemode(fd, 0);
409 strncpy(asset->vcodec, quicktime_video_compressor(fd, 0), 4);
411 // If DV stream, get the timecode
412 // This should become part of libquicktime functionality... for all formats
413 if(match4(asset->vcodec, QUICKTIME_DV))
416 dv_decoder_t *tmp_decoder = dv_decoder_new(0,0,0);
417 VFrame *frame = new VFrame(0, 0, 0, BC_COMPRESSED);
420 set_video_position(0);
422 if(dv_parse_header(tmp_decoder, frame->get_data()) > -1)
424 dv_parse_packs(tmp_decoder, frame->get_data());
425 dv_get_timestamp(tmp_decoder, tc);
426 // printf("Timestamp %s\n", tc);
428 float seconds = Units::text_to_seconds(tc,
429 1, // Use 1 as sample rate, doesn't matter
433 // Set tcstart if it hasn't been set yet, this is a bit problematic
434 // FIXME: The problem arises if file has nonzero tcstart and user manualy sets it to zero - every time project will load it will be set to nonzero
435 if (asset->tcstart == 0)
436 asset->tcstart = int64_t(seconds * asset->frame_rate);
439 dv_decoder_free(tmp_decoder);
447 int64_t FileMOV::get_memory_usage()
451 int64_t result = quicktime_memory_usage(fd);
452 //printf("FileMOV::get_memory_usage 1 %d\n", result);
458 int FileMOV::colormodel_supported(int colormodel)
463 int FileMOV::get_best_colormodel(Asset_GC asset, int driver)
470 case PLAYBACK_X11_XV:
471 case PLAYBACK_ASYNCHRONOUS:
472 if(match4(asset->vcodec, QUICKTIME_YUV420)) return BC_YUV420P;
473 if(match4(asset->vcodec, QUICKTIME_YUV422)) return BC_YUV422;
474 if(match4(asset->vcodec, QUICKTIME_2VUY)) return BC_YUV422;
475 if(match4(asset->vcodec, QUICKTIME_JPEG)) return BC_YUV420P;
476 if(match4(asset->vcodec, QUICKTIME_MJPA)) return BC_YUV422P;
477 if(match4(asset->vcodec, QUICKTIME_DV)) return BC_YUV422;
478 if(match4(asset->vcodec, QUICKTIME_DVSD)) return BC_YUV422;
479 if(match4(asset->vcodec, QUICKTIME_HV60)) return BC_YUV420P;
480 if(match4(asset->vcodec, QUICKTIME_DIVX)) return BC_YUV420P;
481 if(match4(asset->vcodec, QUICKTIME_DVCP)) return BC_YUV422;
482 if(match4(asset->vcodec, QUICKTIME_DVSD)) return BC_YUV422;
483 if(match4(asset->vcodec, QUICKTIME_MP4V)) return BC_YUV420P;
484 if(match4(asset->vcodec, QUICKTIME_H263)) return BC_YUV420P;
485 if(match4(asset->vcodec, QUICKTIME_H264)) return BC_YUV420P;
486 if(match4(asset->vcodec, QUICKTIME_HV64)) return BC_YUV420P;
487 if(match4(asset->vcodec, QUICKTIME_DIV3) ||
488 match4(asset->vcodec, QUICKTIME_SVQ3)) return BC_YUV420P;
490 case PLAYBACK_X11_GL:
491 if(match4(asset->vcodec, QUICKTIME_YUV420) ||
492 match4(asset->vcodec, QUICKTIME_YUV422) ||
493 match4(asset->vcodec, QUICKTIME_2VUY) ||
494 match4(asset->vcodec, QUICKTIME_JPEG) ||
495 match4(asset->vcodec, QUICKTIME_MJPA) ||
496 match4(asset->vcodec, QUICKTIME_DV) ||
497 match4(asset->vcodec, QUICKTIME_DVCP) ||
498 match4(asset->vcodec, QUICKTIME_DVSD) ||
499 match4(asset->vcodec, QUICKTIME_HV60) ||
500 match4(asset->vcodec, QUICKTIME_DIVX) ||
501 match4(asset->vcodec, QUICKTIME_DVSD) ||
502 match4(asset->vcodec, QUICKTIME_MP4V) ||
503 match4(asset->vcodec, QUICKTIME_H263) ||
504 match4(asset->vcodec, QUICKTIME_H264) ||
505 match4(asset->vcodec, QUICKTIME_HV64) ||
506 match4(asset->vcodec, QUICKTIME_DIV3) ||
507 match4(asset->vcodec, QUICKTIME_DVSD)) return BC_YUV888;
509 case PLAYBACK_DV1394:
510 case PLAYBACK_FIREWIRE:
511 if(match4(asset->vcodec, QUICKTIME_DV) ||
512 match4(asset->vcodec, QUICKTIME_DVSD) ||
513 match4(asset->vcodec, QUICKTIME_DVCP)) return BC_COMPRESSED;
518 if(match4(asset->vcodec, QUICKTIME_MJPA))
519 return BC_COMPRESSED;
525 if(!strncasecmp(asset->vcodec, QUICKTIME_YUV420, 4)) return BC_YUV422;
527 if(!strncasecmp(asset->vcodec, QUICKTIME_YUV422, 4)) return BC_YUV422;
529 if(!strncasecmp(asset->vcodec, QUICKTIME_YUV411, 4)) return BC_YUV411P;
531 if(!strncasecmp(asset->vcodec, QUICKTIME_JPEG, 4)) return BC_YUV420P;
533 if(!strncasecmp(asset->vcodec, QUICKTIME_MJPA, 4)) return BC_YUV422P;
535 if(!strncasecmp(asset->vcodec, QUICKTIME_HV60, 4)) return BC_YUV420P;
537 if(!strncasecmp(asset->vcodec, QUICKTIME_DIVX, 4)) return BC_YUV420P;
539 if(!strncasecmp(asset->vcodec, QUICKTIME_H263, 4)) return BC_YUV420P;
541 if(!strncasecmp(asset->vcodec, QUICKTIME_DIV3, 4)) return BC_YUV420P;
545 case VIDEO4LINUX2JPEG:
546 if(!strncasecmp(asset->vcodec, QUICKTIME_MJPA, 4))
547 return BC_COMPRESSED;
551 case CAPTURE_FIREWIRE:
552 case CAPTURE_IEC61883:
553 if(!strncasecmp(asset->vcodec, QUICKTIME_DV, 4) ||
554 !strncasecmp(asset->vcodec, QUICKTIME_DVSD, 4) ||
555 !strncasecmp(asset->vcodec, QUICKTIME_DVCP, 4))
556 return BC_COMPRESSED;
564 int FileMOV::can_copy_from(Edit *edit, int64_t position)
568 //printf("FileMOV::can_copy_from 1 %d %s %s\n", edit->asset->format, edit->asset->vcodec, this->asset->vcodec);
569 if(edit->asset->format == FILE_JPEG_LIST &&
570 match4(this->asset->vcodec, QUICKTIME_JPEG))
573 if((edit->asset->format == FILE_MOV ||
574 edit->asset->format == FILE_AVI))
576 //printf("FileMOV::can_copy_from %s %s\n", edit->asset->vcodec, this->asset->vcodec);
577 if(match4(edit->asset->vcodec, this->asset->vcodec))
579 // there are combinations where the same codec has multiple fourcc codes
583 if (match4(edit->asset->vcodec, QUICKTIME_DV) ||
584 match4(edit->asset->vcodec, QUICKTIME_DVSD) ||
585 match4(edit->asset->vcodec, QUICKTIME_DVCP))
587 if (match4(this->asset->vcodec, QUICKTIME_DV) ||
588 match4(this->asset->vcodec, QUICKTIME_DVSD) ||
589 match4(this->asset->vcodec, QUICKTIME_DVCP))
591 if (is_this_dv && is_edit_dv)
595 if(edit->asset->format == FILE_RAWDV)
597 if(match4(this->asset->vcodec, QUICKTIME_DV) ||
598 match4(this->asset->vcodec, QUICKTIME_DVSD) ||
599 match4(this->asset->vcodec, QUICKTIME_DVCP))
608 int64_t FileMOV::get_audio_length()
611 int64_t result = quicktime_audio_length(fd, 0) + samples_correction;
616 int FileMOV::set_audio_position(int64_t x)
619 // quicktime sets positions for each track seperately so store position in audio_position
620 if(x >= 0 && x < asset->audio_length)
621 return quicktime_set_audio_position(fd, x, 0);
626 int FileMOV::set_video_position(int64_t x)
629 if(x >= 0 && x < asset->video_length)
631 int result = quicktime_set_video_position(fd, x, file->current_layer);
638 void FileMOV::new_audio_temp(int64_t len)
640 if(temp_allocated && temp_allocated < len)
642 for(int i = 0; i < asset->channels; i++)
643 delete [] temp_float[i];
644 delete [] temp_float;
650 temp_allocated = len;
651 temp_float = new float*[asset->channels];
652 for(int i = 0; i < asset->channels; i++)
653 temp_float[i] = new float[len];
659 int FileMOV::write_samples(double **buffer, int64_t len)
663 int result = 0, track_channels = 0;
668 if(quicktime_supported_audio(fd, 0))
670 // Use Quicktime's compressor. (Always used)
671 // Allocate temp buffer
674 // Copy to float buffer
675 for(i = 0; i < asset->channels; i++)
677 for(j = 0; j < len; j++)
679 temp_float[i][j] = buffer[i][j];
683 // Because of the way Quicktime's compressors work we want to limit the chunk
684 // size to speed up decompression.
686 channel_ptr = new float*[asset->channels];
688 for(j = 0; j < len && !result; )
690 chunk_size = asset->sample_rate;
691 if(j + chunk_size > len) chunk_size = len - j;
693 for(i = 0; i < asset->channels; i++)
695 channel_ptr[i] = &temp_float[i][j];
698 result = quicktime_encode_audio(fd, 0, channel_ptr, chunk_size);
699 j += asset->sample_rate;
702 delete [] channel_ptr;
707 int FileMOV::write_frames(VFrame ***frames, int len)
709 //printf("FileMOV::write_frames 1\n");
710 int i, j, k, result = 0;
711 int default_compressor = 1;
714 for(i = 0; i < asset->layers && !result; i++)
721 // Fix direct copy cases for format conversions.
722 if(frames[i][0]->get_color_model() == BC_COMPRESSED)
724 default_compressor = 0;
725 for(j = 0; j < len && !result; j++)
727 VFrame *frame = frames[i][j];
731 // Special handling for DIVX
732 // Determine keyframe status.
733 // Write VOL header in the first frame if none exists
734 if(!strcmp(asset->vcodec, QUICKTIME_DIVX) ||
735 !strcmp(asset->vcodec, QUICKTIME_H263) ||
736 !strcmp(asset->vcodec, QUICKTIME_HV60))
738 if(quicktime_mpeg4_is_key(frame->get_data(),
739 frame->get_compressed_size(),
741 quicktime_insert_keyframe(fd, file->current_frame + j, i);
745 if(!(file->current_frame + j) &&
746 !quicktime_mpeg4_has_vol(frame->get_data()))
748 VFrame *temp_frame = new VFrame;
750 temp_frame->allocate_compressed_data(frame->get_compressed_size() +
752 int bytes = quicktime_mpeg4_write_vol(temp_frame->get_data(),
757 memcpy(temp_frame->get_data() + bytes,
759 frame->get_compressed_size());
760 temp_frame->set_compressed_size(frame->get_compressed_size() + bytes);
762 result = quicktime_write_frame(fd,
763 temp_frame->get_data(),
764 temp_frame->get_compressed_size(),
773 result = quicktime_write_frame(fd,
775 frame->get_compressed_size(),
780 // Determine keyframe status
781 if(!strcmp(asset->vcodec, QUICKTIME_H264) ||
782 !strcmp(asset->vcodec, QUICKTIME_HV64) ||
783 !strcmp(asset->vcodec, QUICKTIME_MP4V))
785 if(frame->get_keyframe() || file->current_frame + j == 0)
786 quicktime_insert_keyframe(fd, file->current_frame + j, i);
789 result = quicktime_write_frame(fd,
791 frame->get_compressed_size(),
795 if(!strcmp(asset->vcodec, QUICKTIME_DIV3))
797 if(quicktime_mpeg4_is_key(frame->get_data(),
798 frame->get_compressed_size(),
800 quicktime_insert_keyframe(fd, file->current_frame + j, i);
801 result = quicktime_write_frame(fd,
803 frame->get_compressed_size(),
807 if(!strcmp(asset->vcodec, QUICKTIME_MJPA))
811 // Create extra space for markers
812 if(frame->get_compressed_allocated() - frame->get_compressed_size() < 0x100)
813 frame->allocate_compressed_data(frame->get_compressed_size() + 0x100);
815 unsigned char *data = frame->get_data();
816 long data_size = frame->get_compressed_size();
817 long data_allocated = frame->get_compressed_allocated();
819 // Sometimes get 0 length frames
822 if(asset->format == FILE_MOV)
824 mjpeg_insert_quicktime_markers(&data,
832 mjpeg_insert_avi_markers(&data,
838 frame->set_compressed_size(data_size);
839 result = quicktime_write_frame(fd,
841 frame->get_compressed_size(),
846 eprintf("data_size=%d\n", data_size);
850 result = quicktime_write_frame(fd,
852 frame->get_compressed_size(),
859 if(match4(asset->vcodec, QUICKTIME_YUV420) ||
860 match4(asset->vcodec, QUICKTIME_2VUY) ||
861 match4(asset->vcodec, QUICKTIME_YUV422) ||
862 match4(asset->vcodec, QUICKTIME_RAW))
864 // Direct copy planes where possible
865 default_compressor = 0;
866 for(j = 0; j < len && !result; j++)
868 VFrame *frame = frames[i][j];
869 //printf("FileMOV::write_frames 1 %d\n", frame->get_color_model());
870 quicktime_set_cmodel(fd, frame->get_color_model());
871 if(cmodel_is_planar(frame->get_color_model()))
873 unsigned char *planes[3];
874 planes[0] = frame->get_y();
875 planes[1] = frame->get_u();
876 planes[2] = frame->get_v();
877 result = quicktime_encode_video(fd, planes, i);
881 result = quicktime_encode_video(fd, frame->get_rows(), i);
882 //printf("FileMOV::write_frames 2 %d\n", result);
884 //printf("FileMOV::write_frames 2\n");
889 (match4(asset->vcodec, QUICKTIME_JPEG) ||
890 match4(asset->vcodec, QUICKTIME_MJPA)))
892 default_compressor = 0;
893 // Compress symmetrically on an SMP system.
894 ThreadStruct *threadframe;
895 int fields = match4(asset->vcodec, QUICKTIME_MJPA) ? 2 : 1;
897 // Set up threads for symmetric compression.
900 threads = new FileMOVThread*[file->cpus];
901 for(j = 0; j < file->cpus; j++)
903 threads[j] = new FileMOVThread(this, fields);
904 threads[j]->start_encoding();
908 // Set up the frame structures for asynchronous compression.
909 // The mjpeg object must exist in each threadframe because it is where the output
911 while(threadframes.total < len)
913 threadframes.append(threadframe = new ThreadStruct);
916 // Load thread frame structures with new frames.
917 for(j = 0; j < len; j++)
919 VFrame *frame = frames[i][j];
920 threadframes.values[j]->input = frame;
921 threadframes.values[j]->completion_lock->lock("FileMOV::write_frames 1");
923 total_threadframes = len;
924 current_threadframe = 0;
926 // Start the threads compressing
927 for(j = 0; j < file->cpus; j++)
929 threads[j]->encode_buffer();
933 // Write the frames as they're finished
934 for(j = 0; j < len; j++)
936 threadframes.values[j]->completion_lock->lock("FileMOV::write_frames 1");
937 threadframes.values[j]->completion_lock->unlock();
940 result = quicktime_write_frame(fd,
941 threadframes.values[j]->output,
942 threadframes.values[j]->output_size,
948 if(default_compressor)
950 //printf("FileMOV::write_frames 3\n");
951 // Use the library's built in compressor.
952 for(j = 0; j < len && !result; j++)
954 //printf("FileMOV::write_frames 4\n");
955 VFrame *frame = frames[i][j];
956 quicktime_set_cmodel(fd, frame->get_color_model());
957 //printf("FileMOV::write_frames 5\n");
958 if(cmodel_is_planar(frame->get_color_model()))
960 unsigned char *planes[3];
961 planes[0] = frame->get_y();
962 planes[1] = frame->get_u();
963 planes[2] = frame->get_v();
964 result = quicktime_encode_video(fd, planes, i);
968 result = quicktime_encode_video(fd, frame->get_rows(), i);
972 //printf("FileMOV::write_frames 4\n");
976 //printf("FileMOV::write_frames 100 %d\n", result);
982 int FileMOV::read_frame(VFrame *frame)
987 switch(frame->get_color_model())
990 frame->allocate_compressed_data(quicktime_frame_size(fd, file->current_frame, file->current_layer));
991 frame->set_compressed_size(quicktime_frame_size(fd, file->current_frame, file->current_layer));
992 frame->set_keyframe((quicktime_get_keyframe_before(fd,
994 file->current_layer) == file->current_frame));
995 //printf("FileMOV::read_frame 1 %lld %d\n", file->current_frame, frame->get_keyframe());
996 result = !quicktime_read_frame(fd,
998 file->current_layer);
1005 unsigned char *row_pointers[3];
1006 row_pointers[0] = frame->get_y();
1007 row_pointers[1] = frame->get_u();
1008 row_pointers[2] = frame->get_v();
1010 quicktime_set_cmodel(fd, frame->get_color_model());
1011 result = quicktime_decode_video(fd,
1013 file->current_layer);
1019 quicktime_set_cmodel(fd, frame->get_color_model());
1020 result = quicktime_decode_video(fd,
1022 file->current_layer);
1023 //for(int i = 0; i < 10000; i++) frame->get_rows()[0][i] = 0xff;
1028 eprintf("quicktime_read_frame/quicktime_decode_video failed, result:\n");
1038 int64_t FileMOV::compressed_frame_size()
1041 return quicktime_frame_size(fd, file->current_frame, file->current_layer);
1044 int FileMOV::read_compressed_frame(VFrame *buffer)
1049 result = quicktime_read_frame(fd, buffer->get_data(), file->current_layer);
1050 buffer->set_compressed_size(result);
1051 buffer->set_keyframe((quicktime_get_keyframe_before(fd,
1052 file->current_frame,
1053 file->current_layer) == file->current_frame));
1058 int FileMOV::write_compressed_frame(VFrame *buffer)
1063 result = quicktime_write_frame(fd,
1065 buffer->get_compressed_size(),
1066 file->current_layer);
1072 int FileMOV::read_raw(VFrame *frame,
1073 float in_x1, float in_y1, float in_x2, float in_y2,
1074 float out_x1, float out_y1, float out_x2, float out_y2,
1075 int use_float, int interpolate)
1077 int64_t i, color_channels, result = 0;
1080 quicktime_set_video_position(fd, file->current_frame, file->current_layer);
1081 // Develop importing strategy
1082 switch(frame->get_color_model())
1085 result = quicktime_decode_video(fd, frame->get_rows(), file->current_layer);
1091 case BC_RGBA16161616:
1099 case BC_YUVA16161616:
1108 int FileMOV::read_samples(double *buffer, int64_t len)
1110 int qt_track, qt_channel;
1114 if(quicktime_track_channels(fd, 0) > file->current_channel &&
1115 quicktime_supported_audio(fd, 0))
1118 //printf("FileMOV::read_samples 2 %ld %ld\n", file->current_sample, quicktime_audio_position(fd, 0));
1119 new_audio_temp(len);
1121 //printf("FileMOV::read_samples 3 %ld %ld\n", file->current_sample, quicktime_audio_position(fd, 0));
1122 if(quicktime_decode_audio(fd, 0, temp_float[0], len, file->current_channel))
1124 eprintf("quicktime_decode_audio failed\n");
1129 for(int i = 0; i < len; i++) buffer[i] = temp_float[0][i];
1132 // if(file->current_channel == 0)
1133 // for(int i = 0; i < len; i++)
1136 // value = (int16_t)(temp_float[0][i] * 32767);
1137 // fwrite(&value, 2, 1, stdout);
1139 //printf("FileMOV::read_samples 4 %ld %ld\n", file->current_sample, quicktime_audio_position(fd, 0));
1146 char* FileMOV::strtocompression(char *string)
1148 if(!strcasecmp(string, _(DIVX_NAME))) return QUICKTIME_DIVX;
1149 if(!strcasecmp(string, _(H264_NAME))) return QUICKTIME_H264;
1150 if(!strcasecmp(string, _(HV64_NAME))) return QUICKTIME_HV64;
1151 if(!strcasecmp(string, _(MP4V_NAME))) return QUICKTIME_MP4V;
1152 if(!strcasecmp(string, _(H263_NAME))) return QUICKTIME_H263;
1153 if(!strcasecmp(string, _(HV60_NAME))) return QUICKTIME_HV60;
1154 if(!strcasecmp(string, _(DIV3_NAME))) return QUICKTIME_DIV3;
1155 // Students say QUICKTIME_DV is required for compression even though
1156 // QUICKTIME_DVSD is produced by other software
1157 // if(!strcasecmp(string, _(DV_NAME))) return QUICKTIME_DVSD;
1158 if(!strcasecmp(string, _(DV_NAME))) return QUICKTIME_DV;
1159 if(!strcasecmp(string, _(PNG_NAME))) return QUICKTIME_PNG;
1160 if(!strcasecmp(string, _(PNGA_NAME))) return MOV_PNGA;
1161 if(!strcasecmp(string, _(RGB_NAME))) return QUICKTIME_RAW;
1162 if(!strcasecmp(string, _(RGBA_NAME))) return MOV_RGBA;
1163 if(!strcasecmp(string, _(QTJPEG_NAME))) return QUICKTIME_JPEG;
1164 if(!strcasecmp(string, _(MJPA_NAME))) return QUICKTIME_MJPA;
1165 if(!strcasecmp(string, _(YUV420_NAME))) return QUICKTIME_YUV420;
1166 if(!strcasecmp(string, _(YUV411_NAME))) return QUICKTIME_YUV411;
1167 if(!strcasecmp(string, _(YUV422_NAME))) return QUICKTIME_YUV422;
1168 if(!strcasecmp(string, _(TWOVUY_NAME))) return QUICKTIME_2VUY;
1169 if(!strcasecmp(string, _(YUV444_NAME))) return QUICKTIME_YUV444;
1170 if(!strcasecmp(string, _(YUVA4444_NAME))) return QUICKTIME_YUVA4444;
1171 if(!strcasecmp(string, _(YUV444_10BIT_NAME))) return QUICKTIME_YUV444_10bit;
1173 if(!strcasecmp(string, _(TWOS_NAME))) return QUICKTIME_TWOS;
1174 if(!strcasecmp(string, _(RAW_NAME))) return QUICKTIME_RAW;
1175 if(!strcasecmp(string, _(IMA4_NAME))) return QUICKTIME_IMA4;
1176 if(!strcasecmp(string, _(ULAW_NAME))) return QUICKTIME_ULAW;
1177 if(!strcasecmp(string, _(MP3_NAME))) return QUICKTIME_MP3;
1178 if(!strcasecmp(string, _(MP4A_NAME))) return QUICKTIME_MP4A;
1179 if(!strcasecmp(string, _(VORBIS_NAME))) return QUICKTIME_VORBIS;
1183 return QUICKTIME_RAW;
1186 char* FileMOV::compressiontostr(char *string)
1188 if(match4(string, QUICKTIME_H263)) return _(H263_NAME);
1189 if(match4(string, QUICKTIME_H264)) return _(H264_NAME);
1190 if(match4(string, QUICKTIME_HV64)) return _(HV64_NAME);
1191 if(match4(string, QUICKTIME_DIVX)) return _(DIVX_NAME);
1192 if(match4(string, QUICKTIME_MP4V)) return _(MP4V_NAME);
1193 if(match4(string, QUICKTIME_HV60)) return _(HV60_NAME);
1194 if(match4(string, QUICKTIME_DIV3)) return _(DIV3_NAME);
1195 if(match4(string, QUICKTIME_DV)) return _(DV_NAME);
1196 if(match4(string, QUICKTIME_DVCP)) return _(DV_NAME);
1197 if(match4(string, QUICKTIME_DVSD)) return _(DV_NAME);
1198 if(match4(string, MOV_PNGA)) return _(PNGA_NAME);
1199 if(match4(string, QUICKTIME_RAW)) return _(RGB_NAME);
1200 if(match4(string, MOV_RGBA)) return _(RGBA_NAME);
1201 if(match4(string, QUICKTIME_JPEG)) return _(QTJPEG_NAME);
1202 if(match4(string, QUICKTIME_MJPA)) return _(MJPA_NAME);
1203 if(match4(string, QUICKTIME_YUV420)) return _(YUV420_NAME);
1204 if(match4(string, QUICKTIME_YUV411)) return _(YUV411_NAME);
1205 if(match4(string, QUICKTIME_YUV422)) return _(YUV422_NAME);
1206 if(match4(string, QUICKTIME_2VUY)) return _(TWOVUY_NAME);
1207 if(match4(string, QUICKTIME_YUV444)) return _(YUV444_NAME);
1208 if(match4(string, QUICKTIME_YUVA4444)) return _(YUVA4444_NAME);
1209 if(match4(string, QUICKTIME_YUV444_10bit)) return _(YUV444_10BIT_NAME);
1215 if(match4(string, QUICKTIME_TWOS)) return _(TWOS_NAME);
1216 if(match4(string, QUICKTIME_RAW)) return _(RAW_NAME);
1217 if(match4(string, QUICKTIME_IMA4)) return _(IMA4_NAME);
1218 if(match4(string, QUICKTIME_ULAW)) return _(ULAW_NAME);
1219 if(match4(string, QUICKTIME_MP3)) return _(MP3_NAME);
1220 if(match4(string, QUICKTIME_MP4A)) return _(MP4A_NAME);
1221 if(match4(string, QUICKTIME_VORBIS)) return _(VORBIS_NAME);
1225 return _("Unknown");
1232 ThreadStruct::ThreadStruct()
1236 output_allocated = 0;
1238 completion_lock = new Condition(1, "ThreadStruct::completion_lock");
1241 ThreadStruct::~ThreadStruct()
1243 if(output) delete [] output;
1244 delete completion_lock;
1247 void ThreadStruct::load_output(mjpeg_t *mjpeg)
1249 if(output_allocated < mjpeg_output_size(mjpeg))
1256 output_allocated = mjpeg_output_size(mjpeg);
1257 output = new unsigned char[output_allocated];
1260 output_size = mjpeg_output_size(mjpeg);
1261 memcpy(output, mjpeg_output_buffer(mjpeg), output_size);
1265 FileMOVThread::FileMOVThread(FileMOV *filemov, int fields) : Thread()
1267 this->filemov = filemov;
1268 this->fields = fields;
1270 input_lock = new Condition(1, "FileMOVThread::input_lock");
1273 FileMOVThread::~FileMOVThread()
1278 int FileMOVThread::start_encoding()
1280 mjpeg = mjpeg_new(filemov->asset->width,
1281 filemov->asset->height,
1283 mjpeg_set_quality(mjpeg, filemov->asset->jpeg_quality);
1284 mjpeg_set_float(mjpeg, 0);
1287 input_lock->lock("FileMOVThread::start_encoding");
1291 int FileMOVThread::stop_encoding()
1294 input_lock->unlock();
1296 if(mjpeg) mjpeg_delete(mjpeg);
1299 int FileMOVThread::encode_buffer()
1301 input_lock->unlock();
1304 void FileMOVThread::run()
1308 input_lock->lock("FileMOVThread::run");
1312 // Get a frame to compress.
1313 filemov->threadframe_lock->lock("FileMOVThread::stop_encoding");
1314 if(filemov->current_threadframe < filemov->total_threadframes)
1316 // Frame is available to process.
1317 input_lock->unlock();
1318 threadframe = filemov->threadframes.values[filemov->current_threadframe];
1319 VFrame *frame = threadframe->input;
1321 filemov->current_threadframe++;
1322 filemov->threadframe_lock->unlock();
1324 mjpeg_compress(mjpeg,
1329 frame->get_color_model(),
1334 unsigned char *data = mjpeg_output_buffer(mjpeg);
1335 long data_size = mjpeg_output_size(mjpeg);
1336 long data_allocated = mjpeg_output_allocated(mjpeg);
1339 if(filemov->asset->format == FILE_MOV)
1341 mjpeg_insert_quicktime_markers(&data,
1349 mjpeg_insert_avi_markers(&data,
1355 mjpeg_set_output_size(mjpeg, data_size);
1357 threadframe->load_output(mjpeg);
1358 threadframe->completion_lock->unlock();
1361 filemov->threadframe_lock->unlock();
1371 MOVConfigAudio::MOVConfigAudio(BC_WindowBase *parent_window, Asset_GC asset)
1372 : BC_Window(PROGRAM_NAME ": Audio Compression",
1373 parent_window->get_abs_cursor_x(1),
1374 parent_window->get_abs_cursor_y(1),
1382 this->parent_window = parent_window;
1383 this->asset = asset;
1384 compression_popup = 0;
1390 MOVConfigAudio::~MOVConfigAudio()
1392 if(compression_popup) delete compression_popup;
1393 if(bits_popup) delete bits_popup;
1394 compression_items.remove_all_objects();
1398 void MOVConfigAudio::reset()
1403 vorbis_min_bitrate = 0;
1405 vorbis_max_bitrate = 0;
1412 int MOVConfigAudio::create_objects()
1417 BC_RelocatableWidget *rw;
1420 if(asset->format == FILE_MOV)
1422 compression_items.append(new BC_ListBoxItem(_(TWOS_NAME)));
1423 compression_items.append(new BC_ListBoxItem(_(RAW_NAME)));
1424 compression_items.append(new BC_ListBoxItem(_(IMA4_NAME)));
1425 compression_items.append(new BC_ListBoxItem(_(MP3_NAME)));
1426 compression_items.append(new BC_ListBoxItem(_(ULAW_NAME)));
1427 compression_items.append(new BC_ListBoxItem(_(VORBIS_NAME)));
1428 compression_items.append(new BC_ListBoxItem(_(MP4A_NAME)));
1432 compression_items.append(new BC_ListBoxItem(_(TWOS_NAME)));
1433 compression_items.append(new BC_ListBoxItem(_(MP3_NAME)));
1434 compression_items.append(new BC_ListBoxItem(_(VORBIS_NAME)));
1435 compression_items.append(new BC_ListBoxItem(_(MP4A_NAME)));
1439 add_tool(new BC_Title(x, y, _("Compression:")));
1441 compression_popup = new MOVConfigAudioPopup(this, x, y);
1442 compression_popup->create_objects();
1444 wg2 = add_widgetgrid(new BC_WidgetGrid(11, 10, 10, 10, 3, 3));
1446 wg2->add(compression_popup, 0, 1);
1448 wg = add_widgetgrid(new BC_WidgetGrid(12, 10, 10, 10, 3, 15));
1452 add_subwindow(new BC_OKButton(this));
1453 ok_height = rw->get_h();
1454 update_parameters();
1459 void MOVConfigAudio::update_parameters()
1462 if(bits_title) delete bits_title;
1463 if(bits_popup) delete bits_popup;
1464 if(dither) delete dither;
1465 if(vorbis_min_bitrate) delete vorbis_min_bitrate;
1466 if(vorbis_bitrate) delete vorbis_bitrate;
1467 if(vorbis_max_bitrate) delete vorbis_max_bitrate;
1468 if(vorbis_vbr) delete vorbis_vbr;
1469 if(mp3_bitrate) delete mp3_bitrate;
1470 delete mp4a_bitrate;
1471 delete mp4a_quantqual;
1475 // deletion of the old wg_set isn't required as the BC_WindowBase clean all created wg_sets
1476 wg_set = add_widgetgrid(new BC_WidgetGrid(10, 10, 10, 10, 10, 3));
1477 wg->add(wg_set, 1, 0);
1478 wg->set_align(1, 0, BC_WidgetGrid::VALIGN_TOP, BC_WidgetGrid::HALIGN_CENTER);
1482 if(!strcasecmp(asset->acodec, QUICKTIME_TWOS) ||
1483 !strcasecmp(asset->acodec, QUICKTIME_RAW))
1485 add_subwindow(bits_title = new BC_Title(x, y, _("Bits per channel:")));
1486 bits_popup = new BitsPopup(this,
1495 bits_popup->create_objects();
1496 wg_set->add(bits_title, wg_row, 0);
1497 wg_set->add(bits_popup, wg_row++, 1);
1499 add_subwindow(dither = new BC_CheckBox(x, y, &asset->dither, _("Dither")));
1500 wg_set->add(dither, wg_row++, 0);
1503 if(!strcasecmp(asset->acodec, QUICKTIME_IMA4))
1507 if(!strcasecmp(asset->acodec, QUICKTIME_MP3))
1509 mp3_bitrate = new MOVConfigAudioNum(this,
1513 &asset->mp3_bitrate);
1514 mp3_bitrate->set_increment(1000);
1515 mp3_bitrate->create_objects();
1516 add_subwindow(mp3_bitrate->title = new BC_Title(x, y, _("Bitrate:")));
1517 wg_set->add(mp3_bitrate->title, wg_row, 0);
1518 wg_set->add(mp3_bitrate, wg_row++, 1);
1521 if(!strcasecmp(asset->acodec, QUICKTIME_ULAW))
1525 if(!strcasecmp(asset->acodec, QUICKTIME_VORBIS))
1527 add_subwindow(vorbis_vbr = new MOVConfigAudioToggle(this,
1528 _("Variable bitrate"),
1531 &asset->vorbis_vbr));
1532 wg_set->add(vorbis_vbr, wg_row++, 1);
1534 vorbis_min_bitrate = new MOVConfigAudioNum(this,
1538 &asset->vorbis_min_bitrate);
1539 vorbis_min_bitrate->set_increment(1000);
1540 add_subwindow(vorbis_min_bitrate->title = new BC_Title(x, y, _("Min bitrate:")));
1541 wg_set->add(vorbis_min_bitrate->title, wg_row, 0);
1542 wg_set->add(vorbis_min_bitrate, wg_row++, 1);
1544 vorbis_bitrate = new MOVConfigAudioNum(this,
1548 &asset->vorbis_bitrate);
1549 vorbis_bitrate->set_increment(1000);
1550 add_subwindow(vorbis_bitrate->title = new BC_Title(x, y, _("Avg bitrate:")));
1551 wg_set->add(vorbis_bitrate->title, wg_row, 0);
1552 wg_set->add(vorbis_bitrate, wg_row++, 1);
1554 vorbis_max_bitrate = new MOVConfigAudioNum(this,
1558 &asset->vorbis_max_bitrate);
1559 vorbis_max_bitrate->set_increment(1000);
1560 add_subwindow(vorbis_max_bitrate->title = new BC_Title(x, y, _("Max bitrate:")));
1561 wg_set->add(vorbis_max_bitrate->title, wg_row, 0);
1562 wg_set->add(vorbis_max_bitrate, wg_row++, 1);
1566 vorbis_min_bitrate->create_objects();
1567 vorbis_bitrate->create_objects();
1568 vorbis_max_bitrate->create_objects();
1571 if(!strcasecmp(asset->acodec, QUICKTIME_MP4A))
1573 mp4a_bitrate = new MOVConfigAudioNum(this,
1577 &asset->mp4a_bitrate);
1578 mp4a_bitrate->set_increment(1000);
1579 mp4a_bitrate->create_objects();
1580 add_subwindow(mp4a_bitrate->title = new BC_Title(x, y, _("Bitrate:")));
1581 wg_set->add(mp4a_bitrate->title, wg_row, 0);
1582 wg_set->add(mp4a_bitrate, wg_row++, 1);
1585 mp4a_quantqual = new MOVConfigAudioNum(this,
1586 _("Quantization Quality (%):"),
1589 &asset->mp4a_quantqual);
1590 mp4a_quantqual->set_increment(1);
1591 mp4a_quantqual->create_objects();
1592 add_subwindow(mp4a_quantqual->title = new BC_Title(x, y, _("Quantization Quality (%):")));
1593 wg_set->add(mp4a_quantqual->title, wg_row, 0);
1594 wg_set->add(mp4a_quantqual, wg_row++, 1);
1597 resize_window(wg->get_w_wm(), wg->get_h_wm() + ok_height);
1600 int MOVConfigAudio::close_event()
1610 MOVConfigAudioToggle::MOVConfigAudioToggle(MOVConfigAudio *popup,
1615 : BC_CheckBox(x, y, *output, title_text)
1617 this->popup = popup;
1618 this->output = output;
1620 int MOVConfigAudioToggle::handle_event()
1622 *output = get_value();
1630 MOVConfigAudioNum::MOVConfigAudioNum(MOVConfigAudio *popup, char *title_text, int x, int y, int *output)
1631 : BC_TumbleTextBox(popup,
1635 popup->get_w() - 150,
1639 this->popup = popup;
1640 this->title_text = title_text;
1641 this->output = output;
1646 MOVConfigAudioNum::~MOVConfigAudioNum()
1648 if(!popup->get_deleting()) delete title;
1651 void MOVConfigAudioNum::create_objects()
1653 BC_TumbleTextBox::create_objects();
1656 int MOVConfigAudioNum::handle_event()
1658 *output = atol(get_text());
1669 MOVConfigAudioPopup::MOVConfigAudioPopup(MOVConfigAudio *popup, int x, int y)
1670 : BC_PopupTextBox(popup,
1671 &popup->compression_items,
1672 FileMOV::compressiontostr(popup->asset->acodec),
1678 this->popup = popup;
1681 int MOVConfigAudioPopup::handle_event()
1683 strcpy(popup->asset->acodec, FileMOV::strtocompression(get_text()));
1684 popup->update_parameters();
1704 MOVConfigVideo::MOVConfigVideo(BC_WindowBase *parent_window,
1706 char *locked_compressor)
1707 : BC_Window(PROGRAM_NAME ": Video Compression",
1708 parent_window->get_abs_cursor_x(1),
1709 parent_window->get_abs_cursor_y(1),
1717 this->parent_window = parent_window;
1718 this->asset = asset;
1719 this->locked_compressor = locked_compressor;
1720 compression_popup = 0;
1727 MOVConfigVideo::~MOVConfigVideo()
1729 if(compression_popup) delete compression_popup;
1730 compression_items.remove_all_objects();
1733 int MOVConfigVideo::create_objects()
1737 BC_RelocatableWidget *rw;
1740 if(asset->format == FILE_MOV)
1742 compression_items.append(new BC_ListBoxItem(_(H264_NAME)));
1743 compression_items.append(new BC_ListBoxItem(_(HV64_NAME)));
1744 // compression_items.append(new BC_ListBoxItem(_(DIVX_NAME)));
1745 compression_items.append(new BC_ListBoxItem(_(MP4V_NAME)));
1746 compression_items.append(new BC_ListBoxItem(_(HV60_NAME)));
1747 compression_items.append(new BC_ListBoxItem(_(DIV3_NAME)));
1748 compression_items.append(new BC_ListBoxItem(_(DV_NAME)));
1749 compression_items.append(new BC_ListBoxItem(_(QTJPEG_NAME)));
1750 compression_items.append(new BC_ListBoxItem(_(MJPA_NAME)));
1751 compression_items.append(new BC_ListBoxItem(_(PNG_NAME)));
1752 compression_items.append(new BC_ListBoxItem(_(PNGA_NAME)));
1753 compression_items.append(new BC_ListBoxItem(_(RGB_NAME)));
1754 compression_items.append(new BC_ListBoxItem(_(RGBA_NAME)));
1755 compression_items.append(new BC_ListBoxItem(_(YUV420_NAME)));
1756 compression_items.append(new BC_ListBoxItem(_(YUV422_NAME)));
1757 compression_items.append(new BC_ListBoxItem(_(TWOVUY_NAME)));
1758 compression_items.append(new BC_ListBoxItem(_(YUV444_NAME)));
1759 compression_items.append(new BC_ListBoxItem(_(YUVA4444_NAME)));
1760 compression_items.append(new BC_ListBoxItem(_(YUV444_10BIT_NAME)));
1764 compression_items.append(new BC_ListBoxItem(_(H264_NAME)));
1765 compression_items.append(new BC_ListBoxItem(_(HV64_NAME)));
1766 // compression_items.append(new BC_ListBoxItem(_(DIVX_NAME)));
1767 compression_items.append(new BC_ListBoxItem(_(MP4V_NAME)));
1768 compression_items.append(new BC_ListBoxItem(_(HV60_NAME)));
1769 compression_items.append(new BC_ListBoxItem(_(DIV3_NAME)));
1770 compression_items.append(new BC_ListBoxItem(_(DV_NAME)));
1771 compression_items.append(new BC_ListBoxItem(_(QTJPEG_NAME)));
1772 compression_items.append(new BC_ListBoxItem(_(MJPA_NAME)));
1773 compression_items.append(new BC_ListBoxItem(_(PNG_NAME)));
1777 add_subwindow(new BC_Title(x, y, _("Compression:")));
1780 wg2 = add_widgetgrid(new BC_WidgetGrid(11, 10, 10, 10, 3, 3));
1783 if(!locked_compressor)
1785 compression_popup = new MOVConfigVideoPopup(this, x, y);
1786 compression_popup->create_objects();
1787 wg2->add(compression_popup, 0, 1);
1792 add_subwindow(new BC_Title(x,
1794 FileMOV::compressiontostr(locked_compressor),
1802 wg = add_widgetgrid(new BC_WidgetGrid(12, 10, 10, 10, 3, 15));
1809 add_subwindow(new BC_OKButton(this));
1810 ok_height = rw->get_h();
1812 update_parameters();
1817 int MOVConfigVideo::close_event()
1824 void MOVConfigVideo::reset()
1827 jpeg_quality_title = 0;
1831 divx_rc_reaction_ratio = 0;
1832 divx_rc_reaction_period = 0;
1833 divx_max_key_interval = 0;
1834 divx_max_quantizer = 0;
1835 divx_min_quantizer = 0;
1838 divx_fix_bitrate = 0;
1843 h264_fix_bitrate = 0;
1847 ms_bitrate_tolerance = 0;
1848 ms_quantization = 0;
1855 void MOVConfigVideo::update_parameters()
1859 delete jpeg_quality_title;
1860 delete jpeg_quality;
1863 if(divx_bitrate) delete divx_bitrate;
1864 if(divx_rc_period) delete divx_rc_period;
1865 if(divx_rc_reaction_ratio) delete divx_rc_reaction_ratio;
1866 if(divx_rc_reaction_period) delete divx_rc_reaction_period;
1867 if(divx_max_key_interval) delete divx_max_key_interval;
1868 if(divx_max_quantizer) delete divx_max_quantizer;
1869 if(divx_min_quantizer) delete divx_min_quantizer;
1870 if(divx_quantizer) delete divx_quantizer;
1871 if(divx_quality) delete divx_quality;
1872 if(divx_fix_quant) delete divx_fix_quant;
1873 if(divx_fix_bitrate) delete divx_fix_bitrate;
1875 if(ms_bitrate) delete ms_bitrate;
1876 if(ms_bitrate_tolerance) delete ms_bitrate_tolerance;
1877 if(ms_interlaced) delete ms_interlaced;
1878 if(ms_quantization) delete ms_quantization;
1879 if(ms_gop_size) delete ms_gop_size;
1880 if(ms_fix_bitrate) delete ms_fix_bitrate;
1881 if(ms_fix_quant) delete ms_fix_quant;
1883 delete h264_bitrate;
1884 delete h264_quantizer;
1885 delete h264_fix_bitrate;
1886 delete h264_fix_quant;
1890 // deletion of the old wg_set isn't required as the BC_WindowBase clean all created wg_sets
1891 wg_set = add_widgetgrid(new BC_WidgetGrid(10, 10, 10, 10, 10, 3));
1892 wg->add(wg_set, 1, 0);
1893 wg->set_align(1, 0, BC_WidgetGrid::VALIGN_TOP, BC_WidgetGrid::HALIGN_CENTER);
1896 char *vcodec = asset->vcodec;
1897 if(locked_compressor) vcodec = locked_compressor;
1901 if(!strcmp(vcodec, QUICKTIME_H264) ||
1902 !strcmp(vcodec, QUICKTIME_HV64))
1904 int x = param_x, y = param_y;
1905 h264_bitrate = new MOVConfigVideoNum(this,
1909 &asset->h264_bitrate);
1910 h264_bitrate->set_increment(1000000);
1911 h264_bitrate->create_objects();
1912 add_subwindow(h264_fix_bitrate = new MOVConfigVideoFixBitrate(x + 260,
1914 &asset->h264_fix_bitrate,
1916 add_subwindow(h264_bitrate->title = new BC_Title(x, y, _("Bitrate:")));
1917 wg_set->add(h264_bitrate->title, wg_row, 0);
1918 wg_set->add(h264_bitrate, wg_row, 1);
1919 wg_set->add(h264_fix_bitrate, wg_row++, 2);
1921 h264_quantizer = new MOVConfigVideoNum(this,
1927 &asset->h264_quantizer);
1928 h264_quantizer->create_objects();
1929 add_subwindow(h264_fix_quant = new MOVConfigVideoFixQuant(x + 260,
1931 &asset->h264_fix_bitrate,
1933 h264_fix_bitrate->opposite = h264_fix_quant;
1934 h264_fix_quant->opposite = h264_fix_bitrate;
1935 add_subwindow(h264_quantizer->title = new BC_Title(x, y, _("Quantization:")));
1936 wg_set->add(h264_quantizer->title, wg_row, 0);
1937 wg_set->add(h264_quantizer, wg_row, 1);
1938 wg_set->add(h264_fix_quant, wg_row++, 2);
1941 // ffmpeg parameters
1942 if(!strcmp(vcodec, QUICKTIME_MP4V) ||
1943 !strcmp(vcodec, QUICKTIME_DIV3))
1945 int x = param_x, y = param_y;
1946 ms_bitrate = new MOVConfigVideoNum(this,
1950 &asset->ms_bitrate);
1951 ms_bitrate->set_increment(1000000);
1952 ms_bitrate->create_objects();
1953 add_subwindow(ms_fix_bitrate = new MOVConfigVideoFixBitrate(x + 260,
1955 &asset->ms_fix_bitrate,
1957 add_subwindow(ms_bitrate->title = new BC_Title(x, y, _("Bitrate:")));
1958 wg_set->add(ms_bitrate->title, wg_row, 0);
1959 wg_set->add(ms_bitrate, wg_row, 1);
1960 wg_set->add(ms_fix_bitrate, wg_row++, 2);
1963 ms_bitrate_tolerance = new MOVConfigVideoNum(this,
1964 _("Bitrate tolerance:"),
1967 &asset->ms_bitrate_tolerance);
1968 ms_bitrate_tolerance->create_objects();
1969 add_subwindow(ms_bitrate_tolerance->title = new BC_Title(x, y, _("Bitrate tolerance:")));
1970 wg_set->add(ms_bitrate_tolerance->title, wg_row, 0);
1971 wg_set->add(ms_bitrate_tolerance, wg_row++, 1);
1973 ms_quantization = new MOVConfigVideoNum(this,
1977 &asset->ms_quantization);
1978 ms_quantization->create_objects();
1979 add_subwindow(ms_fix_quant = new MOVConfigVideoFixQuant(x + 260,
1981 &asset->ms_fix_bitrate,
1983 ms_fix_bitrate->opposite = ms_fix_quant;
1984 ms_fix_quant->opposite = ms_fix_bitrate;
1985 add_subwindow(ms_quantization->title = new BC_Title(x, y, _("Quantization:")));
1986 wg_set->add(ms_quantization->title, wg_row, 0);
1987 wg_set->add(ms_quantization, wg_row, 1);
1988 wg_set->add(ms_fix_quant, wg_row++, 2);
1992 add_subwindow(ms_interlaced = new MOVConfigVideoCheckBox(_("Interlaced"),
1995 &asset->ms_interlaced));
1996 wg_set->add(ms_interlaced, wg_row++, 1);
1998 ms_gop_size = new MOVConfigVideoNum(this,
1999 _("Keyframe interval:"),
2002 &asset->ms_gop_size);
2003 ms_gop_size->create_objects();
2004 add_subwindow(ms_gop_size->title = new BC_Title(x, y, _("Keyframe interval:")));
2005 wg_set->add(ms_gop_size->title, wg_row, 0);
2006 wg_set->add(ms_gop_size, wg_row++, 1);
2009 // OpenDivx parameters
2010 if(!strcmp(vcodec, QUICKTIME_DIVX) ||
2011 !strcmp(vcodec, QUICKTIME_H263) ||
2012 !strcmp(vcodec, QUICKTIME_HV60))
2014 int x = param_x, y = param_y;
2015 divx_bitrate = new MOVConfigVideoNum(this,
2019 &asset->divx_bitrate);
2020 divx_bitrate->set_increment(1000000);
2021 divx_bitrate->create_objects();
2022 add_subwindow(divx_fix_bitrate =
2023 new MOVConfigVideoFixBitrate(x + 260,
2025 &asset->divx_fix_bitrate,
2027 add_subwindow(divx_bitrate->title = new BC_Title(x, y, _("Bitrate:")));
2028 wg_set->add(divx_bitrate->title, wg_row, 0);
2029 wg_set->add(divx_bitrate, wg_row, 1);
2030 wg_set->add(divx_fix_bitrate, wg_row++, 2);
2032 divx_quantizer = new MOVConfigVideoNum(this,
2036 &asset->divx_quantizer);
2037 divx_quantizer->create_objects();
2038 add_subwindow(divx_fix_quant =
2039 new MOVConfigVideoFixQuant(x + 260,
2041 &asset->divx_fix_bitrate,
2043 divx_fix_quant->opposite = divx_fix_bitrate;
2044 divx_fix_bitrate->opposite = divx_fix_quant;
2045 add_subwindow(divx_quantizer->title = new BC_Title(x, y, _("Quantizer:")));
2046 wg_set->add(divx_quantizer->title, wg_row, 0);
2047 wg_set->add(divx_quantizer, wg_row, 1);
2048 wg_set->add(divx_fix_quant, wg_row++, 2);
2050 divx_rc_period = new MOVConfigVideoNum(this,
2054 &asset->divx_rc_period);
2055 divx_rc_period->create_objects();
2056 add_subwindow(divx_rc_period->title = new BC_Title(x, y, _("RC Period:")));
2057 wg_set->add(divx_rc_period->title, wg_row, 0);
2058 wg_set->add(divx_rc_period, wg_row++, 1);
2060 divx_rc_reaction_ratio = new MOVConfigVideoNum(this,
2061 _("Reaction Ratio:"),
2064 &asset->divx_rc_reaction_ratio);
2065 divx_rc_reaction_ratio->create_objects();
2066 add_subwindow(divx_rc_reaction_ratio->title = new BC_Title(x, y, _("Reaction Ratio:")));
2067 wg_set->add(divx_rc_reaction_ratio->title, wg_row, 0);
2068 wg_set->add(divx_rc_reaction_ratio, wg_row++, 1);
2070 divx_rc_reaction_period = new MOVConfigVideoNum(this,
2071 _("Reaction Period:"),
2074 &asset->divx_rc_reaction_period);
2075 divx_rc_reaction_period->create_objects();
2076 add_subwindow(divx_rc_reaction_period->title = new BC_Title(x, y, _("Reaction Period:")));
2077 wg_set->add(divx_rc_reaction_period->title, wg_row, 0);
2078 wg_set->add(divx_rc_reaction_period, wg_row++, 1);
2080 divx_max_key_interval = new MOVConfigVideoNum(this,
2081 _("Max Key Interval:"),
2084 &asset->divx_max_key_interval);
2085 divx_max_key_interval->create_objects();
2086 add_subwindow(divx_max_key_interval->title = new BC_Title(x, y, _("Max Key Interval:")));
2087 wg_set->add(divx_max_key_interval->title, wg_row, 0);
2088 wg_set->add(divx_max_key_interval, wg_row++, 1);
2090 divx_max_quantizer = new MOVConfigVideoNum(this,
2091 _("Max Quantizer:"),
2094 &asset->divx_max_quantizer);
2095 divx_max_quantizer->create_objects();
2096 add_subwindow(divx_max_quantizer->title = new BC_Title(x, y, _("Max Quantizer:")));
2097 wg_set->add(divx_max_quantizer->title, wg_row, 0);
2098 wg_set->add(divx_max_quantizer, wg_row++, 1);
2100 divx_min_quantizer = new MOVConfigVideoNum(this,
2101 _("Min Quantizer:"),
2104 &asset->divx_min_quantizer);
2105 divx_min_quantizer->create_objects();
2106 add_subwindow(divx_min_quantizer->title = new BC_Title(x, y, _("Min Quantizer:")));
2107 wg_set->add(divx_min_quantizer->title, wg_row, 0);
2108 wg_set->add(divx_min_quantizer, wg_row++, 1);
2110 divx_quality = new MOVConfigVideoNum(this,
2114 &asset->divx_quality);
2115 divx_quality->create_objects();
2116 add_subwindow(divx_quality->title = new BC_Title(x, y, _("Quality:")));
2117 wg_set->add(divx_quality->title, wg_row, 0);
2118 wg_set->add(divx_quality, wg_row++, 1);
2121 if(!strcmp(vcodec, QUICKTIME_JPEG) ||
2122 !strcmp(vcodec, QUICKTIME_MJPA))
2124 add_subwindow(jpeg_quality_title = new BC_Title(param_x, param_y, _("Quality:")));
2125 add_subwindow(jpeg_quality = new BC_ISlider(param_x + 80,
2132 asset->jpeg_quality,
2135 &asset->jpeg_quality));
2136 wg_set->add(jpeg_quality_title, wg_row, 0);
2137 wg_set->add(jpeg_quality, wg_row++, 1);
2140 resize_window(wg->get_w_wm(), wg->get_h_wm() + ok_height);
2147 MOVConfigVideoNum::MOVConfigVideoNum(MOVConfigVideo *popup, char *title_text, int x, int y, int *output)
2148 : BC_TumbleTextBox(popup,
2156 this->popup = popup;
2157 this->title_text = title_text;
2158 this->output = output;
2163 MOVConfigVideoNum::MOVConfigVideoNum(MOVConfigVideo *popup,
2170 : BC_TumbleTextBox(popup,
2178 this->popup = popup;
2179 this->title_text = title_text;
2180 this->output = output;
2185 MOVConfigVideoNum::~MOVConfigVideoNum()
2187 if(!popup->get_deleting()) delete title;
2190 void MOVConfigVideoNum::create_objects()
2192 // popup->add_subwindow(title = new BC_Title(x, y, title_text));
2193 BC_TumbleTextBox::create_objects();
2196 int MOVConfigVideoNum::handle_event()
2198 *output = atol(get_text());
2208 MOVConfigVideoCheckBox::MOVConfigVideoCheckBox(char *title_text, int x, int y, int *output)
2209 : BC_CheckBox(x, y, *output, title_text)
2211 this->output = output;
2214 int MOVConfigVideoCheckBox::handle_event()
2216 *output = get_value();
2225 MOVConfigVideoFixBitrate::MOVConfigVideoFixBitrate(int x,
2234 this->output = output;
2235 this->value = value;
2238 int MOVConfigVideoFixBitrate::handle_event()
2241 opposite->update(0);
2250 MOVConfigVideoFixQuant::MOVConfigVideoFixQuant(int x,
2257 _("Fix quantization"))
2259 this->output = output;
2260 this->value = value;
2263 int MOVConfigVideoFixQuant::handle_event()
2266 opposite->update(0);
2274 MOVConfigVideoPopup::MOVConfigVideoPopup(MOVConfigVideo *popup, int x, int y)
2275 : BC_PopupTextBox(popup,
2276 &popup->compression_items,
2277 FileMOV::compressiontostr(popup->asset->vcodec),
2283 this->popup = popup;
2286 int MOVConfigVideoPopup::handle_event()
2288 strcpy(popup->asset->vcodec, FileMOV::strtocompression(get_text()));
2289 popup->update_parameters();
2304 // c-file-style: "linux"