r969: Render format selector: Do not change the path name when the format is changed.
[cinelerra_cv/ct.git] / cinelerra / filemov.C
blobe5699bbf27b08116ecb5eb72bf84c47b42b6acea
1 #include "asset.h"
2 #include "bcsignals.h"
3 #include "bitspopup.h"
4 #include "byteorder.h"
5 #include "condition.h"
6 #include "edit.h"
7 #include "file.h"
8 #include "filemov.h"
9 #include "guicast.h"
10 #include "language.h"
11 #include "mutex.h"
12 #include "mwindow.inc"
13 #include "vframe.h"
14 #include "videodevice.inc"
15 #include "mainerror.h"
17 #include <unistd.h>
18 #include <libdv/dv.h>
20 #if 0
21 N_("MPEG-4")
22 N_("Dual H.264")
23 N_("Dual MPEG-4")
24 N_("H.264")
25 N_("H.263")
26 N_("Microsoft MPEG-4")
27 N_("DV")
28 N_("PNG")
29 N_("PNG with Alpha")
30 N_("Uncompressed RGB")
31 N_("Uncompressed RGBA")
32 N_("YUV 4:2:0 Planar")
33 N_("Component Y'CbCr 8-bit 4:2:2 (yuv2)")
34 N_("Component Y'CbCr 8-bit 4:2:2 (2vuy)")
35 N_("YUV 4:1:1 Packed")
36 N_("Component Y'CbCr 8-bit 4:4:4")
37 N_("Component Y'CbCrA 8-bit 4:4:4:4")
38 N_("Component Y'CbCr 10-bit 4:4:4")
39 N_("JPEG Photo")
40 N_("Motion JPEG A")
43 N_("Twos complement")
44 N_("Unsigned")
45 N_("IMA-4")
46 N_("U-Law")
47 N_("Vorbis")
48 N_("MP3")
49 N_("MPEG-4 Audio")
50 #endif
52 #define DIVX_NAME "MPEG-4"
53 #define HV64_NAME "Dual H.264"
54 #define MP4V_NAME "MPEG-4 Video"
55 #define H264_NAME "H.264"
56 #define H263_NAME "H.263"
57 #define HV60_NAME "Dual MPEG-4"
58 #define DIV3_NAME "Microsoft MPEG-4"
59 #define DV_NAME "DV"
60 #define PNG_NAME "PNG"
61 #define PNGA_NAME "PNG with Alpha"
62 #define RGB_NAME "Uncompressed RGB"
63 #define RGBA_NAME "Uncompressed RGBA"
64 #define YUV420_NAME "YUV 4:2:0 Planar"
65 #define YUV422_NAME "Component Y'CbCr 8-bit 4:2:2 (yuv2)"
66 #define TWOVUY_NAME "Component Y'CbCr 8-bit 4:2:2 (2vuy)"
67 #define YUV411_NAME "YUV 4:1:1 Packed"
68 #define YUV444_NAME "Component Y'CbCr 8-bit 4:4:4"
69 #define YUVA4444_NAME "Component Y'CbCrA 8-bit 4:4:4:4"
70 #define YUV444_10BIT_NAME "Component Y'CbCr 10-bit 4:4:4"
71 #define QTJPEG_NAME "JPEG Photo"
72 #define MJPA_NAME "Motion JPEG A"
74 #define TWOS_NAME "Twos complement"
75 #define RAW_NAME "Unsigned"
76 #define IMA4_NAME "IMA-4"
77 #define ULAW_NAME "U-Law"
78 //#define VORBIS_NAME "Vorbis"
79 #define MP3_NAME "MP3"
80 #define MP4A_NAME "MPEG-4 Audio"
81 #define VORBIS_NAME "OGG Vorbis"
87 FileMOV::FileMOV(Asset *asset, File *file)
88  : FileBase(asset, file)
90         reset_parameters();
91         if(asset->format == FILE_UNKNOWN)
92                 asset->format = FILE_MOV;
93         asset->byte_order = 0;
94         suffix_number = 0;
95         threadframe_lock = new Mutex("FileMOV::threadframe_lock");
98 FileMOV::~FileMOV()
100 SET_TRACE
101         close_file();
102 SET_TRACE
103         delete threadframe_lock;
104 SET_TRACE
107 void FileMOV::get_parameters(BC_WindowBase *parent_window, 
108         Asset *asset, 
109         BC_WindowBase* &format_window,
110         int audio_options,
111         int video_options,
112         char *locked_compressor)
114         fix_codecs(asset);
115         if(audio_options)
116         {
117                 MOVConfigAudio *window = new MOVConfigAudio(parent_window, asset);
118                 format_window = window;
119                 window->create_objects();
120                 window->run_window();
121                 delete window;
122         }
123         else
124         if(video_options)
125         {
126                 MOVConfigVideo *window = new MOVConfigVideo(parent_window, 
127                         asset, 
128                         locked_compressor);
129                 format_window = window;
130                 window->create_objects();
131                 window->run_window();
132                 delete window;
133         }
136 void FileMOV::fix_codecs(Asset *asset)
138         if(!strcasecmp(asset->vcodec, QUICKTIME_DV) ||
139            !strcasecmp(asset->vcodec, QUICKTIME_DVSD) ||
140            !strcasecmp(asset->vcodec, QUICKTIME_DVCP))
141         {
142 //        printf("AF: %i, AH: %i, VC: %s\n", asset->format, asset->height, asset->vcodec);
143         if (asset->format == FILE_AVI)
144                 strcpy (asset->vcodec, QUICKTIME_DVSD);
145         else if (asset->format == FILE_MOV && asset->height == 576)
146                 strcpy (asset->vcodec, QUICKTIME_DVCP);
147         else if (asset->format == FILE_MOV && asset->height == 480)
148                 strcpy (asset->vcodec, QUICKTIME_DV);
149         }
153 int FileMOV::check_codec_params(Asset *asset)
155         if(!strcasecmp(asset->vcodec, QUICKTIME_DV) ||
156            !strcasecmp(asset->vcodec, QUICKTIME_DVSD) ||
157            !strcasecmp(asset->vcodec, QUICKTIME_DVCP))
158         {
160                 if (!(asset->height == 576 && asset->width == 720) &&
161                     !(asset->height == 480 && asset->width == 720))
162                 {
163                         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);
164                         return 1;
165                 }
166         }
167         return 0;
170 int FileMOV::check_sig(Asset *asset)
172         return quicktime_check_sig(asset->path);
176 int FileMOV::reset_parameters_derived()
178         fd = 0;
179         prev_track = 0;
180         quicktime_atracks = 0;
181         quicktime_vtracks = 0;
182         depth = 24;
183         threads = 0;
184         frames_correction = 0;
185         samples_correction = 0;
186         temp_float = 0;
187         temp_allocated = 0;
191 // Just create the Quicktime objects since this routine is also called
192 // for reopening.
193 int FileMOV::open_file(int rd, int wr)
196         this->rd = rd;
197         this->wr = wr;
199         if(suffix_number == 0) strcpy(prefix_path, asset->path);
201         if(!(fd = quicktime_open(asset->path, rd, wr)))
202         {
203                 eprintf("Error while opening file \"%s\". \n%m\n", asset->path);
204                 return 1;
205         }
207         quicktime_set_cpus(fd, file->cpus);
209         if(rd) format_to_asset();
211         if(wr) 
212         {
213                 asset_to_format();
214                 if (check_codec_params(asset))
215                         return 1;
216         }
217 // Set decoding parameter
218         quicktime_set_parameter(fd, "divx_use_deblocking", &asset->divx_use_deblocking);
220 // Set timecode offset
221         quicktime_set_frame_start(fd, asset->tcstart);
223         return 0;
226 int FileMOV::close_file()
228 //printf("FileMOV::close_file 1 %s\n", asset->path);
229         if(fd)
230         {
231                 if(wr) quicktime_set_framerate(fd, asset->frame_rate);
232                 quicktime_close(fd);
233         }
235 //printf("FileMOV::close_file 1\n");
236         if(threads)
237         {
238                 for(int i = 0; i < file->cpus; i++)
239                 {
240                         threads[i]->stop_encoding();
241                         delete threads[i];
242                 }
243                 delete [] threads;
244                 threads = 0;
245         }
247 //printf("FileMOV::close_file 1\n");
248         threadframes.remove_all_objects();
251         if(temp_float) 
252         {
253                 for(int i = 0; i < asset->channels; i++)
254                         delete [] temp_float[i];
255                 delete [] temp_float;
256         }
258 //printf("FileMOV::close_file 1\n");
259         reset_parameters();
260         FileBase::close_file();
261 //printf("FileMOV::close_file 2\n");
262         return 0;
265 void FileMOV::set_frame_start(int64_t offset)
267         quicktime_set_frame_start(fd, offset);
270 void FileMOV::asset_to_format()
272         if(!fd) return;
273         char audio_codec[5];
275         fix_codecs(asset);
277 // Fix up the Quicktime file.
278         quicktime_set_copyright(fd, _("Made with Cinelerra for Linux"));
279         quicktime_set_info(fd, "Quicktime for Linux");
281         if(asset->audio_data)
282         {
283                 quicktime_atracks = quicktime_set_audio(fd, 
284                                 asset->channels, 
285                                 asset->sample_rate, 
286                                 asset->bits, 
287                                 asset->acodec);
288                 quicktime_set_parameter(fd, "vorbis_vbr", &asset->vorbis_vbr);
289                 quicktime_set_parameter(fd, "vorbis_min_bitrate", &asset->vorbis_min_bitrate);
290                 quicktime_set_parameter(fd, "vorbis_bitrate", &asset->vorbis_bitrate);
291                 quicktime_set_parameter(fd, "vorbis_max_bitrate", &asset->vorbis_max_bitrate);
292                 quicktime_set_parameter(fd, "mp3_bitrate", &asset->mp3_bitrate);
293                 quicktime_set_parameter(fd, "mp4a_bitrate", &asset->mp4a_bitrate);
294         }
296         if(asset->video_data)
297         {
298                 char string[16];
299 // Set up the alpha channel compressors
300                 if(!strcmp(asset->vcodec, MOV_RGBA))
301                 {
302                         strcpy(string, QUICKTIME_RAW);
303                         depth = 32;
304                 }
305                 else
306                 if(!strcmp(asset->vcodec, MOV_PNGA))
307                 {
308                         strcpy(string, QUICKTIME_PNG);
309                         depth = 32;
310                 }
311                 else
312                 if(!strcmp(asset->vcodec, QUICKTIME_YUVA4444))
313                 {
314                         strcpy(string, asset->vcodec);
315                         depth = 32;
316                 }
317                 else
318                 {
319                         strcpy(string, asset->vcodec);
320                         depth = 24;
321                 }
324                 quicktime_vtracks = quicktime_set_video(fd, 
325                                         asset->layers, 
326                                         asset->width, 
327                                         asset->height,
328                                         asset->frame_rate,
329                                         string);
333                 for(int i = 0; i < asset->layers; i++)
334                         quicktime_set_depth(fd, depth, i);
336                 quicktime_set_parameter(fd, "jpeg_quality", &asset->jpeg_quality);
338 // set the compression parameters if there are any
339                 quicktime_set_parameter(fd, "divx_bitrate", &asset->divx_bitrate);
340                 quicktime_set_parameter(fd, "divx_rc_period", &asset->divx_rc_period);
341                 quicktime_set_parameter(fd, "divx_rc_reaction_ratio", &asset->divx_rc_reaction_ratio);
342                 quicktime_set_parameter(fd, "divx_rc_reaction_period", &asset->divx_rc_reaction_period);
343                 quicktime_set_parameter(fd, "divx_max_key_interval", &asset->divx_max_key_interval);
344                 quicktime_set_parameter(fd, "divx_max_quantizer", &asset->divx_max_quantizer);
345                 quicktime_set_parameter(fd, "divx_min_quantizer", &asset->divx_min_quantizer);
346                 quicktime_set_parameter(fd, "divx_quantizer", &asset->divx_quantizer);
347                 quicktime_set_parameter(fd, "divx_quality", &asset->divx_quality);
348                 quicktime_set_parameter(fd, "divx_fix_bitrate", &asset->divx_fix_bitrate);
350                 quicktime_set_parameter(fd, "ffmpeg_bitrate", &asset->ms_bitrate);
351                 quicktime_set_parameter(fd, "ffmpeg_bitrate_tolerance", &asset->ms_bitrate_tolerance);
352                 quicktime_set_parameter(fd, "ffmpeg_interlaced", &asset->ms_interlaced);
353                 quicktime_set_parameter(fd, "ffmpeg_quantizer", &asset->ms_quantization);
354                 quicktime_set_parameter(fd, "ffmpeg_gop_size", &asset->ms_gop_size);
355                 quicktime_set_parameter(fd, "ffmpeg_fix_bitrate", &asset->ms_fix_bitrate);
357                 quicktime_set_parameter(fd, "h264_bitrate", &asset->h264_bitrate);
358                 quicktime_set_parameter(fd, "h264_quantizer", &asset->h264_quantizer);
359                 quicktime_set_parameter(fd, "h264_fix_bitrate", &asset->h264_fix_bitrate);
362         }
364         if(wr && asset->format == FILE_AVI)
365         {
366                 quicktime_set_avi(fd, 1);
367         }
371 void FileMOV::format_to_asset()
373         if(!fd) return;
375         if(quicktime_is_avi(fd)) asset->format = FILE_AVI;
376         asset->audio_data = quicktime_has_audio(fd);
377         if(asset->audio_data)
378         {
379                 asset->channels = 0;
380                 int qt_tracks = quicktime_audio_tracks(fd);
381                 for(int i = 0; i < qt_tracks; i++)
382                         asset->channels += quicktime_track_channels(fd, i);
383         
384                 if(!asset->sample_rate)
385                         asset->sample_rate = quicktime_sample_rate(fd, 0);
386                 asset->bits = quicktime_audio_bits(fd, 0);
387                 asset->audio_length = quicktime_audio_length(fd, 0);
388                 strncpy(asset->acodec, quicktime_audio_compressor(fd, 0), 4);
389         }
391 // determine if the video can be read before declaring video data
392         if(quicktime_has_video(fd) && quicktime_supported_video(fd, 0))
393                         asset->video_data = 1;
395         if(asset->video_data)
396         {
397                 depth = quicktime_video_depth(fd, 0);
398                 asset->layers = quicktime_video_tracks(fd);
399                 asset->width = quicktime_video_width(fd, 0);
400                 asset->height = quicktime_video_height(fd, 0);
401                 asset->video_length = quicktime_video_length(fd, 0);
402 // Don't want a user configured frame rate to get destroyed
403                 if(!asset->frame_rate)
404                         asset->frame_rate = quicktime_frame_rate(fd, 0);
405                 if(!asset->interlace_mode)
406                         asset->interlace_mode = quicktime_video_interlacemode(fd, 0);
408                 strncpy(asset->vcodec, quicktime_video_compressor(fd, 0), 4);
410                 // If DV stream, get the timecode 
411                 // This should become part of libquicktime functionality... for all formats
412                 if(match4(asset->vcodec, QUICKTIME_DV))
413                 {
414                         char tc[12];
415                         dv_decoder_t *tmp_decoder = dv_decoder_new(0,0,0);
416                         VFrame *frame = new VFrame(0, 0, 0, BC_COMPRESSED);
417                         
418                         read_frame(frame);
419                         set_video_position(0);
420                         
421                         if(dv_parse_header(tmp_decoder, frame->get_data()) > -1)
422                         {
423                                 dv_parse_packs(tmp_decoder, frame->get_data());
424                                 dv_get_timestamp(tmp_decoder, tc);
425 //                              printf("Timestamp %s\n", tc);
426                         
427                                 float seconds = Units::text_to_seconds(tc,
428                                                                                 1, // Use 1 as sample rate, doesn't matter
429                                                                                 TIME_HMSF,
430                                                                                 asset->frame_rate,
431                                                                                 0);
432                                 // Set tcstart if it hasn't been set yet, this is a bit problematic
433                                 // 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
434                                 if (asset->tcstart == 0)
435                                         asset->tcstart = int64_t(seconds * asset->frame_rate);
436                         }
437                         delete frame;
438                         dv_decoder_free(tmp_decoder);
439                         
440                 }
443         }
446 int64_t FileMOV::get_memory_usage()
448         if(rd && fd)
449         {
450                 int64_t result = quicktime_memory_usage(fd);
451 //printf("FileMOV::get_memory_usage 1 %d\n", result);
452                 return result;
453         }
454         return 0;
457 int FileMOV::colormodel_supported(int colormodel)
459         return colormodel;
462 int FileMOV::get_best_colormodel(Asset *asset, int driver)
464         switch(driver)
465         {
466                 case PLAYBACK_X11:
467                         return BC_RGB888;
468                         break;
469                 case PLAYBACK_X11_XV:
470                 case PLAYBACK_ASYNCHRONOUS:
471                         if(match4(asset->vcodec, QUICKTIME_YUV420)) return BC_YUV420P;
472                         if(match4(asset->vcodec, QUICKTIME_YUV422)) return BC_YUV422;
473                         if(match4(asset->vcodec, QUICKTIME_2VUY)) return BC_YUV422;
474                         if(match4(asset->vcodec, QUICKTIME_JPEG)) return BC_YUV420P;
475                         if(match4(asset->vcodec, QUICKTIME_MJPA)) return BC_YUV422P;
476                         if(match4(asset->vcodec, QUICKTIME_DV)) return BC_YUV422;
477                         if(match4(asset->vcodec, QUICKTIME_DVSD)) return BC_YUV422;
478                         if(match4(asset->vcodec, QUICKTIME_HV60)) return BC_YUV420P;
479                         if(match4(asset->vcodec, QUICKTIME_DIVX)) return BC_YUV420P;
480                         if(match4(asset->vcodec, QUICKTIME_DVCP)) return BC_YUV422;
481                         if(match4(asset->vcodec, QUICKTIME_DVSD)) return BC_YUV422;
482                         if(match4(asset->vcodec, QUICKTIME_MP4V)) return BC_YUV420P;
483                         if(match4(asset->vcodec, QUICKTIME_H263)) return BC_YUV420P;
484                         if(match4(asset->vcodec, QUICKTIME_H264)) return BC_YUV420P;
485                         if(match4(asset->vcodec, QUICKTIME_HV64)) return BC_YUV420P;
486                         if(match4(asset->vcodec, QUICKTIME_DIV3) ||
487                                 match4(asset->vcodec, QUICKTIME_SVQ3)) return BC_YUV420P;
488                         break;
489                 case PLAYBACK_X11_GL:
490                         if(match4(asset->vcodec, QUICKTIME_YUV420) ||
491                                 match4(asset->vcodec, QUICKTIME_YUV422) ||
492                                 match4(asset->vcodec, QUICKTIME_2VUY) ||
493                                 match4(asset->vcodec, QUICKTIME_JPEG) ||
494                                 match4(asset->vcodec, QUICKTIME_MJPA) ||
495                                 match4(asset->vcodec, QUICKTIME_DV) ||
496                                 match4(asset->vcodec, QUICKTIME_DVCP) ||
497                                 match4(asset->vcodec, QUICKTIME_DVSD) ||
498                                 match4(asset->vcodec, QUICKTIME_HV60) ||
499                                 match4(asset->vcodec, QUICKTIME_DIVX) ||
500                                 match4(asset->vcodec, QUICKTIME_DVSD) ||
501                                 match4(asset->vcodec, QUICKTIME_MP4V) ||
502                                 match4(asset->vcodec, QUICKTIME_H263) ||
503                                 match4(asset->vcodec, QUICKTIME_H264) ||
504                                 match4(asset->vcodec, QUICKTIME_HV64) ||
505                                 match4(asset->vcodec, QUICKTIME_DIV3) || 
506                                 match4(asset->vcodec, QUICKTIME_DVSD)) return BC_YUV888;
507                         break;
508                 case PLAYBACK_DV1394:
509                 case PLAYBACK_FIREWIRE:
510                         if(match4(asset->vcodec, QUICKTIME_DV) || 
511                                 match4(asset->vcodec, QUICKTIME_DVSD) || 
512                                 match4(asset->vcodec, QUICKTIME_DVCP)) return BC_COMPRESSED;
513                         return BC_YUV422P;
514                         break;
515                 case PLAYBACK_LML:
516                 case PLAYBACK_BUZ:
517                         if(match4(asset->vcodec, QUICKTIME_MJPA)) 
518                                 return BC_COMPRESSED;
519                         else
520                                 return BC_YUV422P;
521                         break;
522                 case VIDEO4LINUX:
523                 case VIDEO4LINUX2:
524                         if(!strncasecmp(asset->vcodec, QUICKTIME_YUV420, 4)) return BC_YUV422;
525                         else
526                         if(!strncasecmp(asset->vcodec, QUICKTIME_YUV422, 4)) return BC_YUV422;
527                         else
528                         if(!strncasecmp(asset->vcodec, QUICKTIME_YUV411, 4)) return BC_YUV411P;
529                         else
530                         if(!strncasecmp(asset->vcodec, QUICKTIME_JPEG, 4)) return BC_YUV420P;
531                         else
532                         if(!strncasecmp(asset->vcodec, QUICKTIME_MJPA, 4)) return BC_YUV422P;
533                         else
534                         if(!strncasecmp(asset->vcodec, QUICKTIME_HV60, 4)) return BC_YUV420P;
535                         else
536                         if(!strncasecmp(asset->vcodec, QUICKTIME_DIVX, 4)) return BC_YUV420P;
537                         else
538                         if(!strncasecmp(asset->vcodec, QUICKTIME_H263, 4)) return BC_YUV420P;
539                         else
540                         if(!strncasecmp(asset->vcodec, QUICKTIME_DIV3, 4)) return BC_YUV420P;
541                         break;
542                 case CAPTURE_BUZ:
543                 case CAPTURE_LML:
544                 case VIDEO4LINUX2JPEG:
545                         if(!strncasecmp(asset->vcodec, QUICKTIME_MJPA, 4)) 
546                                 return BC_COMPRESSED;
547                         else
548                                 return BC_YUV422;
549                         break;
550                 case CAPTURE_FIREWIRE:
551                 case CAPTURE_IEC61883:
552                         if(!strncasecmp(asset->vcodec, QUICKTIME_DV, 4) ||
553                                 !strncasecmp(asset->vcodec, QUICKTIME_DVSD, 4) ||
554                                 !strncasecmp(asset->vcodec, QUICKTIME_DVCP, 4)) 
555                                 return BC_COMPRESSED;
556                         else
557                                 return BC_YUV422;
558                         break;
559         }
560         return BC_RGB888;
563 int FileMOV::can_copy_from(Edit *edit, int64_t position)
565         if(!fd) return 0;
567 //printf("FileMOV::can_copy_from 1 %d %s %s\n", edit->asset->format, edit->asset->vcodec, this->asset->vcodec);
568         if(edit->asset->format == FILE_JPEG_LIST && 
569                 match4(this->asset->vcodec, QUICKTIME_JPEG))
570                 return 1;
571         else
572         if((edit->asset->format == FILE_MOV || 
573                 edit->asset->format == FILE_AVI))
574         {
575 //printf("FileMOV::can_copy_from %s %s\n", edit->asset->vcodec, this->asset->vcodec);
576                 if(match4(edit->asset->vcodec, this->asset->vcodec))
577                         return 1;
578 // there are combinations where the same codec has multiple fourcc codes
579 // check for DV...
580                 int is_edit_dv = 0;
581                 int is_this_dv = 0;
582                 if (match4(edit->asset->vcodec, QUICKTIME_DV) || 
583                         match4(edit->asset->vcodec, QUICKTIME_DVSD) || 
584                         match4(edit->asset->vcodec, QUICKTIME_DVCP))
585                         is_edit_dv = 1;
586                 if (match4(this->asset->vcodec, QUICKTIME_DV) || 
587                         match4(this->asset->vcodec, QUICKTIME_DVSD) || 
588                         match4(this->asset->vcodec, QUICKTIME_DVCP))
589                         is_this_dv = 1;
590                 if (is_this_dv && is_edit_dv)
591                         return 1;
592         }
593         else
594         if(edit->asset->format == FILE_RAWDV)
595         {
596                 if(match4(this->asset->vcodec, QUICKTIME_DV) || 
597                         match4(this->asset->vcodec, QUICKTIME_DVSD) || 
598                         match4(this->asset->vcodec, QUICKTIME_DVCP))
599                         return 1;
600         }
603         return 0;
607 int64_t FileMOV::get_audio_length()
609         if(!fd) return 0;
610         int64_t result = quicktime_audio_length(fd, 0) + samples_correction;
612         return result;
615 int FileMOV::set_audio_position(int64_t x)
617         if(!fd) return 1;
618 // quicktime sets positions for each track seperately so store position in audio_position
619         if(x >= 0 && x < asset->audio_length)
620                 return quicktime_set_audio_position(fd, x, 0);
621         else
622                 return 1;
625 int FileMOV::set_video_position(int64_t x)
627         if(!fd) return 1;
628         if(x >= 0 && x < asset->video_length)
629         {
630                 int result = quicktime_set_video_position(fd, x, file->current_layer);
631                 return result;
632         }else
633                 return 1;
637 void FileMOV::new_audio_temp(int64_t len)
639         if(temp_allocated && temp_allocated < len)
640         {
641                 for(int i = 0; i < asset->channels; i++)
642                         delete [] temp_float[i];
643                 delete [] temp_float;
644                 temp_allocated = 0;
645         }
647         if(!temp_allocated)
648         {
649                 temp_allocated = len;
650                 temp_float = new float*[asset->channels];
651                 for(int i = 0; i < asset->channels; i++)
652                         temp_float[i] = new float[len];
653         }
658 int FileMOV::write_samples(double **buffer, int64_t len)
660         int i, j;
661         int64_t bytes;
662         int result = 0, track_channels = 0;
663         int chunk_size;
665         if(!fd) return 0;
667         if(quicktime_supported_audio(fd, 0))
668         {
669 // Use Quicktime's compressor. (Always used)
670 // Allocate temp buffer
671                 new_audio_temp(len);
673 // Copy to float buffer
674                 for(i = 0; i < asset->channels; i++)
675                 {
676                         for(j = 0; j < len; j++)
677                         {
678                                 temp_float[i][j] = buffer[i][j];
679                         }
680                 }
682 // Because of the way Quicktime's compressors work we want to limit the chunk
683 // size to speed up decompression.
684                 float **channel_ptr;
685                 channel_ptr = new float*[asset->channels];
687                 for(j = 0; j < len && !result; )
688                 {
689                         chunk_size = asset->sample_rate;
690                         if(j + chunk_size > len) chunk_size = len - j;
692                         for(i = 0; i < asset->channels; i++)
693                         {
694                                 channel_ptr[i] = &temp_float[i][j];
695                         }
697                         result = quicktime_encode_audio(fd, 0, channel_ptr, chunk_size);
698                         j += asset->sample_rate;
699                 }
701                 delete [] channel_ptr;
702         }
703         return result;
706 int FileMOV::write_frames(VFrame ***frames, int len)
708 //printf("FileMOV::write_frames 1\n");
709         int i, j, k, result = 0;
710         int default_compressor = 1;
711         if(!fd) return 0;
713         for(i = 0; i < asset->layers && !result; i++)
714         {
720 // Fix direct copy cases for format conversions.
721                 if(frames[i][0]->get_color_model() == BC_COMPRESSED)
722                 {
723                         default_compressor = 0;
724                         for(j = 0; j < len && !result; j++)
725                         {
726                                 VFrame *frame = frames[i][j];
730 // Special handling for DIVX
731 // Determine keyframe status.
732 // Write VOL header in the first frame if none exists
733                                 if(!strcmp(asset->vcodec, QUICKTIME_DIVX) ||
734                                         !strcmp(asset->vcodec, QUICKTIME_H263) ||
735                                         !strcmp(asset->vcodec, QUICKTIME_HV60))
736                                 {
737                                         if(quicktime_mpeg4_is_key(frame->get_data(), 
738                                                 frame->get_compressed_size(),
739                                                 asset->vcodec))
740                                                 quicktime_insert_keyframe(fd, file->current_frame + j, i);
743 // Write header
744                                         if(!(file->current_frame + j) && 
745                                                 !quicktime_mpeg4_has_vol(frame->get_data()))
746                                         {
747                                                 VFrame *temp_frame = new VFrame;
749                                                 temp_frame->allocate_compressed_data(frame->get_compressed_size() + 
750                                                         0xff);
751                                                 int bytes = quicktime_mpeg4_write_vol(temp_frame->get_data(),
752                                                         asset->width, 
753                                                         asset->height, 
754                                                         60000, 
755                                                         asset->frame_rate);
756                                                 memcpy(temp_frame->get_data() + bytes, 
757                                                         frame->get_data(), 
758                                                         frame->get_compressed_size());
759                                                 temp_frame->set_compressed_size(frame->get_compressed_size() + bytes);
761                                                 result = quicktime_write_frame(fd,
762                                                         temp_frame->get_data(),
763                                                         temp_frame->get_compressed_size(),
764                                                         i);
766                                                 delete temp_frame;
769                                         }
770                                         else
771                                         {
772                                                 result = quicktime_write_frame(fd,
773                                                         frame->get_data(),
774                                                         frame->get_compressed_size(),
775                                                         i);
776                                         }
777                                 }
778                                 else
779 // Determine keyframe status
780                                 if(!strcmp(asset->vcodec, QUICKTIME_H264) ||
781                                         !strcmp(asset->vcodec, QUICKTIME_HV64) ||
782                                         !strcmp(asset->vcodec, QUICKTIME_MP4V))
783                                 {
784                                         if(frame->get_keyframe() || file->current_frame + j == 0)
785                                                 quicktime_insert_keyframe(fd, file->current_frame + j, i);
787 // Write frame
788                                                 result = quicktime_write_frame(fd,
789                                                         frame->get_data(),
790                                                         frame->get_compressed_size(),
791                                                         i);
792                                 }
793                                 else
794                                 if(!strcmp(asset->vcodec, QUICKTIME_DIV3))
795                                 {
796                                         if(quicktime_mpeg4_is_key(frame->get_data(), 
797                                                 frame->get_compressed_size(),
798                                                 asset->vcodec))
799                                                 quicktime_insert_keyframe(fd, file->current_frame + j, i);
800                                         result = quicktime_write_frame(fd,
801                                                 frame->get_data(),
802                                                 frame->get_compressed_size(),
803                                                 i);
804                                 }
805                                 else
806                                 if(!strcmp(asset->vcodec, QUICKTIME_MJPA))
807                                 {
808                                         long field2_offset;
810 // Create extra space for markers
811                                         if(frame->get_compressed_allocated() - frame->get_compressed_size() < 0x100)
812                                                 frame->allocate_compressed_data(frame->get_compressed_size() + 0x100);
814                                         unsigned char *data = frame->get_data();
815                                         long data_size = frame->get_compressed_size();
816                                         long data_allocated = frame->get_compressed_allocated();
818 // Sometimes get 0 length frames
819                                         if(data_size)
820                                         {
821                                                 if(asset->format == FILE_MOV)
822                                                 {
823                                                         mjpeg_insert_quicktime_markers(&data,
824                                                                 &data_size,
825                                                                 &data_allocated,
826                                                                 2,
827                                                                 &field2_offset);
828                                                 }
829                                                 else
830                                                 {
831                                                         mjpeg_insert_avi_markers(&data,
832                                                                 &data_size,
833                                                                 &data_allocated,
834                                                                 2,
835                                                                 &field2_offset);
836                                                 }
837                                                 frame->set_compressed_size(data_size);
838                                                 result = quicktime_write_frame(fd,
839                                                         frame->get_data(),
840                                                         frame->get_compressed_size(),
841                                                         i);
842                                         }
843                                         else
844                                         {
845                                                 eprintf("data_size=%d\n", data_size);
846                                         }
847                                 }
848                                 else
849                                         result = quicktime_write_frame(fd,
850                                                 frame->get_data(),
851                                                 frame->get_compressed_size(),
852                                                 i);
853                                 
854                                 
855                         }
856                 }
857                 else
858                 if(match4(asset->vcodec, QUICKTIME_YUV420) ||
859                         match4(asset->vcodec, QUICKTIME_2VUY) ||
860                         match4(asset->vcodec, QUICKTIME_YUV422) ||
861                         match4(asset->vcodec, QUICKTIME_RAW))
862                 {
863 // Direct copy planes where possible
864                         default_compressor = 0;
865                         for(j = 0; j < len && !result; j++)
866                         {
867                                 VFrame *frame = frames[i][j];
868 //printf("FileMOV::write_frames 1 %d\n", frame->get_color_model());
869                                 quicktime_set_cmodel(fd, frame->get_color_model());
870                                 if(cmodel_is_planar(frame->get_color_model()))
871                                 {
872                                         unsigned char *planes[3];
873                                         planes[0] = frame->get_y();
874                                         planes[1] = frame->get_u();
875                                         planes[2] = frame->get_v();
876                                         result = quicktime_encode_video(fd, planes, i);
877                                 }
878                                 else
879                                 {
880                                         result = quicktime_encode_video(fd, frame->get_rows(), i);
881 //printf("FileMOV::write_frames 2 %d\n", result);
882                                 }
883 //printf("FileMOV::write_frames 2\n");
884                         }
885                 }
886                 else
887                 if(file->cpus > 1 && 
888                         (match4(asset->vcodec, QUICKTIME_JPEG) || 
889                         match4(asset->vcodec, QUICKTIME_MJPA)))
890                 {
891                         default_compressor = 0;
892 // Compress symmetrically on an SMP system.
893                         ThreadStruct *threadframe;
894                         int fields = match4(asset->vcodec, QUICKTIME_MJPA) ? 2 : 1;
896 // Set up threads for symmetric compression.
897                         if(!threads)
898                         {
899                                 threads = new FileMOVThread*[file->cpus];
900                                 for(j = 0; j < file->cpus; j++)
901                                 {
902                                         threads[j] = new FileMOVThread(this, fields);
903                                         threads[j]->start_encoding();
904                                 }
905                         }
907 // Set up the frame structures for asynchronous compression.
908 // The mjpeg object must exist in each threadframe because it is where the output
909 // is stored.
910                         while(threadframes.total < len)
911                         {
912                                 threadframes.append(threadframe = new ThreadStruct);
913                         }
915 // Load thread frame structures with new frames.
916                         for(j = 0; j < len; j++)
917                         {
918                                 VFrame *frame = frames[i][j];
919                                 threadframes.values[j]->input = frame;
920                                 threadframes.values[j]->completion_lock->lock("FileMOV::write_frames 1");
921                         }
922                         total_threadframes = len;
923                         current_threadframe = 0;
925 // Start the threads compressing
926                         for(j = 0; j < file->cpus; j++)
927                         {
928                                 threads[j]->encode_buffer();
929                         }
932 // Write the frames as they're finished
933                         for(j = 0; j < len; j++)
934                         {
935                                 threadframes.values[j]->completion_lock->lock("FileMOV::write_frames 1");
936                                 threadframes.values[j]->completion_lock->unlock();
937                                 if(!result)
938                                 {
939                                         result = quicktime_write_frame(fd, 
940                                                 threadframes.values[j]->output,
941                                                 threadframes.values[j]->output_size,
942                                                 i);
943                                 }
944                         }
945                 }
947                 if(default_compressor)
948                 {
949 //printf("FileMOV::write_frames 3\n");
950 // Use the library's built in compressor.
951                         for(j = 0; j < len && !result; j++)
952                         {
953 //printf("FileMOV::write_frames 4\n");
954                                 VFrame *frame = frames[i][j];
955                                 quicktime_set_cmodel(fd, frame->get_color_model());
956 //printf("FileMOV::write_frames 5\n");
957                                 if(cmodel_is_planar(frame->get_color_model()))
958                                 {
959                                         unsigned char *planes[3];
960                                         planes[0] = frame->get_y();
961                                         planes[1] = frame->get_u();
962                                         planes[2] = frame->get_v();
963                                         result = quicktime_encode_video(fd, planes, i);
964                                 }
965                                 else
966                                 {
967                                         result = quicktime_encode_video(fd, frame->get_rows(), i);
968                                 }
969                         }
970                 }
971 //printf("FileMOV::write_frames 4\n");
972         }
975 //printf("FileMOV::write_frames 100 %d\n", result);
976         return result;
981 int FileMOV::read_frame(VFrame *frame)
983         if(!fd) return 1;
984         int result = 0;
986         switch(frame->get_color_model())
987         {
988                 case BC_COMPRESSED:
989                         frame->allocate_compressed_data(quicktime_frame_size(fd, file->current_frame, file->current_layer));
990                         frame->set_compressed_size(quicktime_frame_size(fd, file->current_frame, file->current_layer));
991                         frame->set_keyframe((quicktime_get_keyframe_before(fd, 
992                                 file->current_frame, 
993                                 file->current_layer) == file->current_frame));
994 //printf("FileMOV::read_frame 1 %lld %d\n", file->current_frame, frame->get_keyframe());
995                         result = !quicktime_read_frame(fd, 
996                                 frame->get_data(), 
997                                 file->current_layer);
998                         break;
1000 // Progressive
1001                 case BC_YUV420P:
1002                 case BC_YUV422P:
1003                 {
1004                         unsigned char *row_pointers[3];
1005                         row_pointers[0] = frame->get_y();
1006                         row_pointers[1] = frame->get_u();
1007                         row_pointers[2] = frame->get_v();
1009                         quicktime_set_cmodel(fd, frame->get_color_model());
1010                         result = quicktime_decode_video(fd, 
1011                                 row_pointers,
1012                                 file->current_layer);
1013                 }
1014                         break;
1016 // Packed
1017                 default:
1018                         quicktime_set_cmodel(fd, frame->get_color_model());
1019                         result = quicktime_decode_video(fd, 
1020                                 frame->get_rows(),
1021                                 file->current_layer);
1022 //for(int i = 0; i < 10000; i++) frame->get_rows()[0][i] = 0xff;
1023                         break;
1024         }
1025         if (result)
1026         {
1027                 eprintf("quicktime_read_frame/quicktime_decode_video failed, result:\n");
1028         }
1032         return result;
1037 int64_t FileMOV::compressed_frame_size()
1039         if(!fd) return 0;
1040         return quicktime_frame_size(fd, file->current_frame, file->current_layer);
1043 int FileMOV::read_compressed_frame(VFrame *buffer)
1045         int64_t result;
1046         if(!fd) return 0;
1048         result = quicktime_read_frame(fd, buffer->get_data(), file->current_layer);
1049         buffer->set_compressed_size(result);
1050         buffer->set_keyframe((quicktime_get_keyframe_before(fd, 
1051                 file->current_frame, 
1052                 file->current_layer) == file->current_frame));
1053         result = !result;
1054         return result;
1057 int FileMOV::write_compressed_frame(VFrame *buffer)
1059         int result = 0;
1060         if(!fd) return 0;
1062         result = quicktime_write_frame(fd, 
1063                 buffer->get_data(), 
1064                 buffer->get_compressed_size(), 
1065                 file->current_layer);
1066         return result;
1071 int FileMOV::read_raw(VFrame *frame, 
1072                 float in_x1, float in_y1, float in_x2, float in_y2,
1073                 float out_x1, float out_y1, float out_x2, float out_y2, 
1074                 int use_float, int interpolate)
1076         int64_t i, color_channels, result = 0;
1077         if(!fd) return 0;
1079         quicktime_set_video_position(fd, file->current_frame, file->current_layer);
1080 // Develop importing strategy
1081         switch(frame->get_color_model())
1082         {
1083                 case BC_RGB888:
1084                         result = quicktime_decode_video(fd, frame->get_rows(), file->current_layer);
1085                         break;
1086                 case BC_RGBA8888:
1087                         break;
1088                 case BC_RGB161616:
1089                         break;
1090                 case BC_RGBA16161616:
1091                         break;
1092                 case BC_YUV888:
1093                         break;
1094                 case BC_YUVA8888:
1095                         break;
1096                 case BC_YUV161616:
1097                         break;
1098                 case BC_YUVA16161616:
1099                         break;
1100                 case BC_YUV420P:
1101                         break;
1102         }
1103         return result;
1106 // Overlay samples
1107 int FileMOV::read_samples(double *buffer, int64_t len)
1109         int qt_track, qt_channel;
1111         if(!fd) return 0;
1113         if(quicktime_track_channels(fd, 0) > file->current_channel &&
1114                 quicktime_supported_audio(fd, 0))
1115         {
1117 //printf("FileMOV::read_samples 2 %ld %ld\n", file->current_sample, quicktime_audio_position(fd, 0));
1118                 new_audio_temp(len);
1120 //printf("FileMOV::read_samples 3 %ld %ld\n", file->current_sample, quicktime_audio_position(fd, 0));
1121                 if(quicktime_decode_audio(fd, 0, temp_float[0], len, file->current_channel))
1122                 {
1123                         eprintf("quicktime_decode_audio failed\n");
1124                         return 1;
1125                 }
1126                 else
1127                 {
1128                         for(int i = 0; i < len; i++) buffer[i] = temp_float[0][i];
1129                 }
1131 // if(file->current_channel == 0)
1132 // for(int i = 0; i < len; i++)
1133 // {
1134 //      int16_t value;
1135 //      value = (int16_t)(temp_float[0][i] * 32767);
1136 //      fwrite(&value, 2, 1, stdout);
1137 // }
1138 //printf("FileMOV::read_samples 4 %ld %ld\n", file->current_sample, quicktime_audio_position(fd, 0));
1139         }
1141         return 0;
1145 char* FileMOV::strtocompression(char *string)
1147         if(!strcasecmp(string, _(DIVX_NAME))) return QUICKTIME_DIVX;
1148         if(!strcasecmp(string, _(H264_NAME))) return QUICKTIME_H264;
1149         if(!strcasecmp(string, _(HV64_NAME))) return QUICKTIME_HV64;
1150         if(!strcasecmp(string, _(MP4V_NAME))) return QUICKTIME_MP4V;
1151         if(!strcasecmp(string, _(H263_NAME))) return QUICKTIME_H263;
1152         if(!strcasecmp(string, _(HV60_NAME))) return QUICKTIME_HV60;
1153         if(!strcasecmp(string, _(DIV3_NAME))) return QUICKTIME_DIV3;
1154 // Students say QUICKTIME_DV is required for compression even though
1155 // QUICKTIME_DVSD is produced by other software
1156 //      if(!strcasecmp(string, _(DV_NAME))) return QUICKTIME_DVSD;
1157         if(!strcasecmp(string, _(DV_NAME))) return QUICKTIME_DV;
1158         if(!strcasecmp(string, _(PNG_NAME))) return QUICKTIME_PNG;
1159         if(!strcasecmp(string, _(PNGA_NAME))) return MOV_PNGA;
1160         if(!strcasecmp(string, _(RGB_NAME))) return QUICKTIME_RAW;
1161         if(!strcasecmp(string, _(RGBA_NAME))) return MOV_RGBA;
1162         if(!strcasecmp(string, _(QTJPEG_NAME))) return QUICKTIME_JPEG;
1163         if(!strcasecmp(string, _(MJPA_NAME))) return QUICKTIME_MJPA;
1164         if(!strcasecmp(string, _(YUV420_NAME))) return QUICKTIME_YUV420;
1165         if(!strcasecmp(string, _(YUV411_NAME))) return QUICKTIME_YUV411;
1166         if(!strcasecmp(string, _(YUV422_NAME))) return QUICKTIME_YUV422;
1167         if(!strcasecmp(string, _(TWOVUY_NAME))) return QUICKTIME_2VUY;
1168         if(!strcasecmp(string, _(YUV444_NAME))) return QUICKTIME_YUV444;
1169         if(!strcasecmp(string, _(YUVA4444_NAME))) return QUICKTIME_YUVA4444;
1170         if(!strcasecmp(string, _(YUV444_10BIT_NAME))) return QUICKTIME_YUV444_10bit;
1172         if(!strcasecmp(string, _(TWOS_NAME))) return QUICKTIME_TWOS;
1173         if(!strcasecmp(string, _(RAW_NAME))) return QUICKTIME_RAW;
1174         if(!strcasecmp(string, _(IMA4_NAME))) return QUICKTIME_IMA4;
1175         if(!strcasecmp(string, _(ULAW_NAME))) return QUICKTIME_ULAW;
1176         if(!strcasecmp(string, _(MP3_NAME))) return QUICKTIME_MP3;
1177         if(!strcasecmp(string, _(MP4A_NAME))) return QUICKTIME_MP4A;
1178         if(!strcasecmp(string, _(VORBIS_NAME))) return QUICKTIME_VORBIS;
1182         return QUICKTIME_RAW;
1185 char* FileMOV::compressiontostr(char *string)
1187         if(match4(string, QUICKTIME_H263)) return _(H263_NAME);
1188         if(match4(string, QUICKTIME_H264)) return _(H264_NAME);
1189         if(match4(string, QUICKTIME_HV64)) return _(HV64_NAME);
1190         if(match4(string, QUICKTIME_DIVX)) return _(DIVX_NAME);
1191         if(match4(string, QUICKTIME_MP4V)) return _(MP4V_NAME);
1192         if(match4(string, QUICKTIME_HV60)) return _(HV60_NAME);
1193         if(match4(string, QUICKTIME_DIV3)) return _(DIV3_NAME);
1194         if(match4(string, QUICKTIME_DV)) return _(DV_NAME);
1195         if(match4(string, QUICKTIME_DVCP)) return _(DV_NAME);
1196         if(match4(string, QUICKTIME_DVSD)) return _(DV_NAME);
1197         if(match4(string, MOV_PNGA)) return _(PNGA_NAME);
1198         if(match4(string, QUICKTIME_RAW)) return _(RGB_NAME);
1199         if(match4(string, MOV_RGBA)) return _(RGBA_NAME);
1200         if(match4(string, QUICKTIME_JPEG)) return _(QTJPEG_NAME);
1201         if(match4(string, QUICKTIME_MJPA)) return _(MJPA_NAME);
1202         if(match4(string, QUICKTIME_YUV420)) return _(YUV420_NAME);
1203         if(match4(string, QUICKTIME_YUV411)) return _(YUV411_NAME);
1204         if(match4(string, QUICKTIME_YUV422)) return _(YUV422_NAME);
1205         if(match4(string, QUICKTIME_2VUY)) return _(TWOVUY_NAME);
1206         if(match4(string, QUICKTIME_YUV444)) return _(YUV444_NAME);
1207         if(match4(string, QUICKTIME_YUVA4444)) return _(YUVA4444_NAME);
1208         if(match4(string, QUICKTIME_YUV444_10bit)) return _(YUV444_10BIT_NAME);
1214         if(match4(string, QUICKTIME_TWOS)) return _(TWOS_NAME);
1215         if(match4(string, QUICKTIME_RAW)) return _(RAW_NAME);
1216         if(match4(string, QUICKTIME_IMA4)) return _(IMA4_NAME);
1217         if(match4(string, QUICKTIME_ULAW)) return _(ULAW_NAME);
1218         if(match4(string, QUICKTIME_MP3)) return _(MP3_NAME);
1219         if(match4(string, QUICKTIME_MP4A)) return _(MP4A_NAME);
1220         if(match4(string, QUICKTIME_VORBIS)) return _(VORBIS_NAME);
1224         return _("Unknown");
1231 ThreadStruct::ThreadStruct()
1233         input = 0;
1234         output = 0;
1235         output_allocated = 0;
1236         output_size = 0;
1237         completion_lock = new Condition(1, "ThreadStruct::completion_lock");
1240 ThreadStruct::~ThreadStruct()
1242         if(output) delete [] output;
1243         delete completion_lock;
1246 void ThreadStruct::load_output(mjpeg_t *mjpeg)
1248         if(output_allocated < mjpeg_output_size(mjpeg))
1249         {
1250                 delete [] output;
1251                 output = 0;
1252         }
1253         if(!output)
1254         {
1255                 output_allocated = mjpeg_output_size(mjpeg);
1256                 output = new unsigned char[output_allocated];
1257         }
1258         
1259         output_size = mjpeg_output_size(mjpeg);
1260         memcpy(output, mjpeg_output_buffer(mjpeg), output_size);
1264 FileMOVThread::FileMOVThread(FileMOV *filemov, int fields) : Thread()
1266         this->filemov = filemov;
1267         this->fields = fields;
1268         mjpeg = 0;
1269         input_lock = new Condition(1, "FileMOVThread::input_lock");
1272 FileMOVThread::~FileMOVThread()
1274         delete input_lock;
1277 int FileMOVThread::start_encoding()
1279         mjpeg = mjpeg_new(filemov->asset->width, 
1280                 filemov->asset->height, 
1281                 fields);
1282         mjpeg_set_quality(mjpeg, filemov->asset->jpeg_quality);
1283         mjpeg_set_float(mjpeg, 0);
1284         done = 0;
1285         set_synchronous(1);
1286         input_lock->lock("FileMOVThread::start_encoding");
1287         start();
1290 int FileMOVThread::stop_encoding()
1292         done = 1;
1293         input_lock->unlock();
1294         join();
1295         if(mjpeg) mjpeg_delete(mjpeg);
1298 int FileMOVThread::encode_buffer()
1300         input_lock->unlock();
1303 void FileMOVThread::run()
1305         while(!done)
1306         {
1307                 input_lock->lock("FileMOVThread::run");
1309                 if(!done)
1310                 {
1311 // Get a frame to compress.
1312                         filemov->threadframe_lock->lock("FileMOVThread::stop_encoding");
1313                         if(filemov->current_threadframe < filemov->total_threadframes)
1314                         {
1315 // Frame is available to process.
1316                                 input_lock->unlock();
1317                                 threadframe = filemov->threadframes.values[filemov->current_threadframe];
1318                                 VFrame *frame = threadframe->input;
1320                                 filemov->current_threadframe++;
1321                                 filemov->threadframe_lock->unlock();
1323                                 mjpeg_compress(mjpeg, 
1324                                         frame->get_rows(), 
1325                                         frame->get_y(), 
1326                                         frame->get_u(), 
1327                                         frame->get_v(),
1328                                         frame->get_color_model(),
1329                                         1);
1331                                 if(fields > 1)
1332                                 {
1333                                         unsigned char *data = mjpeg_output_buffer(mjpeg);
1334                                         long data_size = mjpeg_output_size(mjpeg);
1335                                         long data_allocated = mjpeg_output_allocated(mjpeg);
1336                                         long field2_offset;
1338                                         if(filemov->asset->format == FILE_MOV)
1339                                         {
1340                                                 mjpeg_insert_quicktime_markers(&data,
1341                                                         &data_size,
1342                                                         &data_allocated,
1343                                                         2,
1344                                                         &field2_offset);
1345                                         }
1346                                         else
1347                                         {
1348                                                 mjpeg_insert_avi_markers(&data,
1349                                                         &data_size,
1350                                                         &data_allocated,
1351                                                         2,
1352                                                         &field2_offset);
1353                                         }
1354                                         mjpeg_set_output_size(mjpeg, data_size);
1355                                 }
1356                                 threadframe->load_output(mjpeg);
1357                                 threadframe->completion_lock->unlock();
1358                         }
1359                         else
1360                                 filemov->threadframe_lock->unlock();
1361                 }
1362         }
1370 MOVConfigAudio::MOVConfigAudio(BC_WindowBase *parent_window, Asset *asset)
1371  : BC_Window(PROGRAM_NAME ": Audio Compression",
1372         parent_window->get_abs_cursor_x(1),
1373         parent_window->get_abs_cursor_y(1),
1374         350,
1375         250)
1377         this->parent_window = parent_window;
1378         this->asset = asset;
1379         compression_popup = 0;
1380         reset();
1383 MOVConfigAudio::~MOVConfigAudio()
1385         if(compression_popup) delete compression_popup;
1386         if(bits_popup) delete bits_popup;
1387         compression_items.remove_all_objects();
1391 void MOVConfigAudio::reset()
1393         bits_popup = 0;
1394         bits_title = 0;
1395         dither = 0;
1396         vorbis_min_bitrate = 0;
1397         vorbis_bitrate = 0;
1398         vorbis_max_bitrate = 0;
1399         vorbis_vbr = 0;
1400         mp3_bitrate = 0;
1401         mp4a_bitrate = 0;
1402         mp4a_quantqual = 0;
1405 int MOVConfigAudio::create_objects()
1407         int x = 10, y = 10;
1410         if(asset->format == FILE_MOV)
1411         {
1412                 compression_items.append(new BC_ListBoxItem(_(TWOS_NAME)));
1413                 compression_items.append(new BC_ListBoxItem(_(RAW_NAME)));
1414                 compression_items.append(new BC_ListBoxItem(_(IMA4_NAME)));
1415                 compression_items.append(new BC_ListBoxItem(_(MP3_NAME)));
1416                 compression_items.append(new BC_ListBoxItem(_(ULAW_NAME)));
1417                 compression_items.append(new BC_ListBoxItem(_(VORBIS_NAME)));
1418                 compression_items.append(new BC_ListBoxItem(_(MP4A_NAME)));
1419         }
1420         else
1421         {
1422                 compression_items.append(new BC_ListBoxItem(_(TWOS_NAME)));
1423                 compression_items.append(new BC_ListBoxItem(_(MP3_NAME)));
1424                 compression_items.append(new BC_ListBoxItem(_(VORBIS_NAME)));
1425                 compression_items.append(new BC_ListBoxItem(_(MP4A_NAME)));
1426         }
1428         add_tool(new BC_Title(x, y, _("Compression:")));
1429         y += 25;
1430         compression_popup = new MOVConfigAudioPopup(this, x, y);
1431         compression_popup->create_objects();
1433         update_parameters();
1435         add_subwindow(new BC_OKButton(this));
1436         return 0;
1439 void MOVConfigAudio::update_parameters()
1441         int x = 10, y = 70;
1442         if(bits_title) delete bits_title;
1443         if(bits_popup) delete bits_popup;
1444         if(dither) delete dither;
1445         if(vorbis_min_bitrate) delete vorbis_min_bitrate;
1446         if(vorbis_bitrate) delete vorbis_bitrate;
1447         if(vorbis_max_bitrate) delete vorbis_max_bitrate;
1448         if(vorbis_vbr) delete vorbis_vbr;
1449         if(mp3_bitrate) delete mp3_bitrate;
1450         delete mp4a_bitrate;
1451         delete mp4a_quantqual;
1453         reset();
1457         if(!strcasecmp(asset->acodec, QUICKTIME_TWOS) ||
1458                 !strcasecmp(asset->acodec, QUICKTIME_RAW))
1459         {
1460                 add_subwindow(bits_title = new BC_Title(x, y, _("Bits per channel:")));
1461                 bits_popup = new BitsPopup(this, 
1462                         x + 150, 
1463                         y, 
1464                         &asset->bits, 
1465                         0, 
1466                         0, 
1467                         0, 
1468                         0, 
1469                         0);
1470                 bits_popup->create_objects();
1471                 y += 40;
1472                 add_subwindow(dither = new BC_CheckBox(x, y, &asset->dither, _("Dither")));
1473         }
1474         else
1475         if(!strcasecmp(asset->acodec, QUICKTIME_IMA4))
1476         {
1477         }
1478         else
1479         if(!strcasecmp(asset->acodec, QUICKTIME_MP3))
1480         {
1481                 mp3_bitrate = new MOVConfigAudioNum(this, 
1482                         _("Bitrate:"), 
1483                         x, 
1484                         y, 
1485                         &asset->mp3_bitrate);
1486                 mp3_bitrate->set_increment(1000);
1487                 mp3_bitrate->create_objects();
1488         }
1489         else
1490         if(!strcasecmp(asset->acodec, QUICKTIME_ULAW))
1491         {
1492         }
1493         else
1494         if(!strcasecmp(asset->acodec, QUICKTIME_VORBIS))
1495         {
1496                 add_subwindow(vorbis_vbr = new MOVConfigAudioToggle(this,
1497                         _("Variable bitrate"),
1498                         x,
1499                         y,
1500                         &asset->vorbis_vbr));
1501                 y += 35;
1502                 vorbis_min_bitrate = new MOVConfigAudioNum(this, 
1503                         _("Min bitrate:"), 
1504                         x, 
1505                         y, 
1506                         &asset->vorbis_min_bitrate);
1507                 vorbis_min_bitrate->set_increment(1000);
1508                 y += 30;
1509                 vorbis_bitrate = new MOVConfigAudioNum(this, 
1510                         _("Avg bitrate:"), 
1511                         x, 
1512                         y, 
1513                         &asset->vorbis_bitrate);
1514                 vorbis_bitrate->set_increment(1000);
1515                 y += 30;
1516                 vorbis_max_bitrate = new MOVConfigAudioNum(this, 
1517                         _("Max bitrate:"), 
1518                         x, 
1519                         y, 
1520                         &asset->vorbis_max_bitrate);
1521                 vorbis_max_bitrate->set_increment(1000);
1525                 vorbis_min_bitrate->create_objects();
1526                 vorbis_bitrate->create_objects();
1527                 vorbis_max_bitrate->create_objects();
1528         }
1529         else
1530         if(!strcasecmp(asset->acodec, QUICKTIME_MP4A))
1531         {
1532                 mp4a_bitrate = new MOVConfigAudioNum(this, 
1533                         _("Bitrate:"), 
1534                         x, 
1535                         y, 
1536                         &asset->mp4a_bitrate);
1537                 mp4a_bitrate->set_increment(1000);
1538                 mp4a_bitrate->create_objects();
1540                 y += 30;
1541                 mp4a_quantqual = new MOVConfigAudioNum(this, 
1542                         _("Quantization Quality (%):"), 
1543                         x, 
1544                         y, 
1545                         &asset->mp4a_quantqual);
1546                 mp4a_quantqual->set_increment(1);
1547                 mp4a_quantqual->create_objects();
1548         }
1551 int MOVConfigAudio::close_event()
1553         set_done(0);
1554         return 1;
1561 MOVConfigAudioToggle::MOVConfigAudioToggle(MOVConfigAudio *popup,
1562         char *title_text,
1563         int x,
1564         int y,
1565         int *output)
1566  : BC_CheckBox(x, y, *output, title_text)
1568         this->popup = popup;
1569         this->output = output;
1571 int MOVConfigAudioToggle::handle_event()
1573         *output = get_value();
1574         return 1;
1581 MOVConfigAudioNum::MOVConfigAudioNum(MOVConfigAudio *popup, char *title_text, int x, int y, int *output)
1582  : BC_TumbleTextBox(popup, 
1583                 (int64_t)*output,
1584                 (int64_t)-1,
1585                 (int64_t)25000000,
1586                 popup->get_w() - 150, 
1587                 y, 
1588                 100)
1590         this->popup = popup;
1591         this->title_text = title_text;
1592         this->output = output;
1593         this->x = x;
1594         this->y = y;
1597 MOVConfigAudioNum::~MOVConfigAudioNum()
1599         if(!popup->get_deleting()) delete title;
1602 void MOVConfigAudioNum::create_objects()
1604         popup->add_subwindow(title = new BC_Title(x, y, title_text));
1605         BC_TumbleTextBox::create_objects();
1608 int MOVConfigAudioNum::handle_event()
1610         *output = atol(get_text());
1611         return 1;
1621 MOVConfigAudioPopup::MOVConfigAudioPopup(MOVConfigAudio *popup, int x, int y)
1622  : BC_PopupTextBox(popup, 
1623                 &popup->compression_items,
1624                 FileMOV::compressiontostr(popup->asset->acodec),
1625                 x, 
1626                 y, 
1627                 300,
1628                 300)
1630         this->popup = popup;
1633 int MOVConfigAudioPopup::handle_event()
1635         strcpy(popup->asset->acodec, FileMOV::strtocompression(get_text()));
1636         popup->update_parameters();
1637         return 1;
1656 MOVConfigVideo::MOVConfigVideo(BC_WindowBase *parent_window, 
1657         Asset *asset, 
1658         char *locked_compressor)
1659  : BC_Window(PROGRAM_NAME ": Video Compression",
1660         parent_window->get_abs_cursor_x(1),
1661         parent_window->get_abs_cursor_y(1),
1662         420,
1663         420)
1665         this->parent_window = parent_window;
1666         this->asset = asset;
1667         this->locked_compressor = locked_compressor;
1668         compression_popup = 0;
1670         reset();
1673 MOVConfigVideo::~MOVConfigVideo()
1675         if(compression_popup) delete compression_popup;
1676         compression_items.remove_all_objects();
1679 int MOVConfigVideo::create_objects()
1681         int x = 10, y = 10;
1683         if(asset->format == FILE_MOV)
1684         {
1685                 compression_items.append(new BC_ListBoxItem(_(H264_NAME)));
1686                 compression_items.append(new BC_ListBoxItem(_(HV64_NAME)));
1687 //              compression_items.append(new BC_ListBoxItem(_(DIVX_NAME)));
1688                 compression_items.append(new BC_ListBoxItem(_(MP4V_NAME)));
1689                 compression_items.append(new BC_ListBoxItem(_(HV60_NAME)));
1690                 compression_items.append(new BC_ListBoxItem(_(DIV3_NAME)));
1691                 compression_items.append(new BC_ListBoxItem(_(DV_NAME)));
1692                 compression_items.append(new BC_ListBoxItem(_(QTJPEG_NAME)));
1693                 compression_items.append(new BC_ListBoxItem(_(MJPA_NAME)));
1694                 compression_items.append(new BC_ListBoxItem(_(PNG_NAME)));
1695                 compression_items.append(new BC_ListBoxItem(_(PNGA_NAME)));
1696                 compression_items.append(new BC_ListBoxItem(_(RGB_NAME)));
1697                 compression_items.append(new BC_ListBoxItem(_(RGBA_NAME)));
1698                 compression_items.append(new BC_ListBoxItem(_(YUV420_NAME)));
1699                 compression_items.append(new BC_ListBoxItem(_(YUV422_NAME)));
1700                 compression_items.append(new BC_ListBoxItem(_(TWOVUY_NAME)));
1701                 compression_items.append(new BC_ListBoxItem(_(YUV444_NAME)));
1702                 compression_items.append(new BC_ListBoxItem(_(YUVA4444_NAME)));
1703                 compression_items.append(new BC_ListBoxItem(_(YUV444_10BIT_NAME)));
1704         }
1705         else
1706         {
1707                 compression_items.append(new BC_ListBoxItem(_(H264_NAME)));
1708                 compression_items.append(new BC_ListBoxItem(_(HV64_NAME)));
1709 //              compression_items.append(new BC_ListBoxItem(_(DIVX_NAME)));
1710                 compression_items.append(new BC_ListBoxItem(_(MP4V_NAME)));
1711                 compression_items.append(new BC_ListBoxItem(_(HV60_NAME)));
1712                 compression_items.append(new BC_ListBoxItem(_(DIV3_NAME)));
1713                 compression_items.append(new BC_ListBoxItem(_(DV_NAME)));
1714                 compression_items.append(new BC_ListBoxItem(_(QTJPEG_NAME)));
1715                 compression_items.append(new BC_ListBoxItem(_(MJPA_NAME)));
1716                 compression_items.append(new BC_ListBoxItem(_(PNG_NAME)));
1717         }
1719         add_subwindow(new BC_Title(x, y, _("Compression:")));
1720         y += 25;
1722         if(!locked_compressor)
1723         {
1724                 compression_popup = new MOVConfigVideoPopup(this, x, y);
1725                 compression_popup->create_objects();
1726         }
1727         else
1728         {
1729                 add_subwindow(new BC_Title(x, 
1730                         y, 
1731                         FileMOV::compressiontostr(locked_compressor),
1732                         MEDIUMFONT,
1733                         RED,
1734                         0));
1735         }
1736         y += 40;
1738         param_x = x;
1739         param_y = y;
1740         update_parameters();
1742         add_subwindow(new BC_OKButton(this));
1743         return 0;
1746 int MOVConfigVideo::close_event()
1748         set_done(0);
1749         return 1;
1753 void MOVConfigVideo::reset()
1755         jpeg_quality = 0;
1756         jpeg_quality_title = 0;
1758         divx_bitrate = 0;
1759         divx_rc_period = 0;
1760         divx_rc_reaction_ratio = 0;
1761         divx_rc_reaction_period = 0;
1762         divx_max_key_interval = 0;
1763         divx_max_quantizer = 0;
1764         divx_min_quantizer = 0;
1765         divx_quantizer = 0;
1766         divx_quality = 0;
1767         divx_fix_bitrate = 0;
1768         divx_fix_quant = 0;
1770         h264_bitrate = 0;
1771         h264_quantizer = 0;
1772         h264_fix_bitrate = 0;
1773         h264_fix_quant = 0;
1775         ms_bitrate = 0;
1776         ms_bitrate_tolerance = 0;
1777         ms_quantization = 0;
1778         ms_interlaced = 0;
1779         ms_gop_size = 0;
1780         ms_fix_bitrate = 0;
1781         ms_fix_quant = 0;
1784 void MOVConfigVideo::update_parameters()
1786         if(jpeg_quality)
1787         {
1788                 delete jpeg_quality_title;
1789                 delete jpeg_quality;
1790         }
1792         if(divx_bitrate) delete divx_bitrate;
1793         if(divx_rc_period) delete divx_rc_period;
1794         if(divx_rc_reaction_ratio) delete divx_rc_reaction_ratio;
1795         if(divx_rc_reaction_period) delete divx_rc_reaction_period;
1796         if(divx_max_key_interval) delete divx_max_key_interval;
1797         if(divx_max_quantizer) delete divx_max_quantizer;
1798         if(divx_min_quantizer) delete divx_min_quantizer;
1799         if(divx_quantizer) delete divx_quantizer;
1800         if(divx_quality) delete divx_quality;
1801         if(divx_fix_quant) delete divx_fix_quant;
1802         if(divx_fix_bitrate) delete divx_fix_bitrate;
1804         if(ms_bitrate) delete ms_bitrate;
1805         if(ms_bitrate_tolerance) delete ms_bitrate_tolerance;
1806         if(ms_interlaced) delete ms_interlaced;
1807         if(ms_quantization) delete ms_quantization;
1808         if(ms_gop_size) delete ms_gop_size;
1809         if(ms_fix_bitrate) delete ms_fix_bitrate;
1810         if(ms_fix_quant) delete ms_fix_quant;
1812         delete h264_bitrate;
1813         delete h264_quantizer;
1814         delete h264_fix_bitrate;
1815         delete h264_fix_quant;
1817         reset();
1820         char *vcodec = asset->vcodec;
1821         if(locked_compressor) vcodec = locked_compressor;
1824 // H264 parameters
1825         if(!strcmp(vcodec, QUICKTIME_H264) ||
1826                 !strcmp(vcodec, QUICKTIME_HV64))
1827         {
1828                 int x = param_x, y = param_y;
1829                 h264_bitrate = new MOVConfigVideoNum(this, 
1830                         _("Bitrate:"), 
1831                         x, 
1832                         y, 
1833                         &asset->h264_bitrate);
1834                 h264_bitrate->set_increment(1000000);
1835                 h264_bitrate->create_objects();
1836                 add_subwindow(h264_fix_bitrate = new MOVConfigVideoFixBitrate(x + 260, 
1837                                 y,
1838                                 &asset->h264_fix_bitrate,
1839                                 1));
1840                 y += 30;
1841                 h264_quantizer = new MOVConfigVideoNum(this, 
1842                         _("Quantization:"), 
1843                         x, 
1844                         y, 
1845                         0,
1846                         51,
1847                         &asset->h264_quantizer);
1848                 h264_quantizer->create_objects();
1849                 add_subwindow(h264_fix_quant = new MOVConfigVideoFixQuant(x + 260, 
1850                                 y,
1851                                 &asset->h264_fix_bitrate,
1852                                 0));
1853                 h264_fix_bitrate->opposite = h264_fix_quant;
1854                 h264_fix_quant->opposite = h264_fix_bitrate;
1855         }
1856         else
1857 // ffmpeg parameters
1858         if(!strcmp(vcodec, QUICKTIME_MP4V) ||
1859                 !strcmp(vcodec, QUICKTIME_DIV3))
1860         {
1861                 int x = param_x, y = param_y;
1862                 ms_bitrate = new MOVConfigVideoNum(this, 
1863                         _("Bitrate:"), 
1864                         x, 
1865                         y, 
1866                         &asset->ms_bitrate);
1867                 ms_bitrate->set_increment(1000000);
1868                 ms_bitrate->create_objects();
1869                 add_subwindow(ms_fix_bitrate = new MOVConfigVideoFixBitrate(x + 260, 
1870                                 y,
1871                                 &asset->ms_fix_bitrate,
1872                                 1));
1873                 y += 30;
1875                 ms_bitrate_tolerance = new MOVConfigVideoNum(this, 
1876                         _("Bitrate tolerance:"), 
1877                         x, 
1878                         y, 
1879                         &asset->ms_bitrate_tolerance);
1880                 ms_bitrate_tolerance->create_objects();
1881                 y += 30;
1882                 ms_quantization = new MOVConfigVideoNum(this, 
1883                         _("Quantization:"), 
1884                         x, 
1885                         y, 
1886                         &asset->ms_quantization);
1887                 ms_quantization->create_objects();
1888                 add_subwindow(ms_fix_quant = new MOVConfigVideoFixQuant(x + 260, 
1889                                 y,
1890                                 &asset->ms_fix_bitrate,
1891                                 0));
1892                 ms_fix_bitrate->opposite = ms_fix_quant;
1893                 ms_fix_quant->opposite = ms_fix_bitrate;
1896                 y += 30;
1897                 add_subwindow(ms_interlaced = new MOVConfigVideoCheckBox(_("Interlaced"), 
1898                         x, 
1899                         y, 
1900                         &asset->ms_interlaced));
1901                 y += 30;
1902                 ms_gop_size = new MOVConfigVideoNum(this, 
1903                         _("Keyframe interval:"), 
1904                         x, 
1905                         y, 
1906                         &asset->ms_gop_size);
1907                 ms_gop_size->create_objects();
1908         }
1909         else
1910 // OpenDivx parameters
1911         if(!strcmp(vcodec, QUICKTIME_DIVX) ||
1912                 !strcmp(vcodec, QUICKTIME_H263) ||
1913                 !strcmp(vcodec, QUICKTIME_HV60))
1914         {
1915                 int x = param_x, y = param_y;
1916                 divx_bitrate = new MOVConfigVideoNum(this, 
1917                         _("Bitrate:"), 
1918                         x, 
1919                         y, 
1920                         &asset->divx_bitrate);
1921                 divx_bitrate->set_increment(1000000);
1922                 divx_bitrate->create_objects();
1923                 add_subwindow(divx_fix_bitrate = 
1924                         new MOVConfigVideoFixBitrate(x + 260, 
1925                                 y,
1926                                 &asset->divx_fix_bitrate,
1927                                 1));
1928                 y += 30;
1929                 divx_quantizer = new MOVConfigVideoNum(this, 
1930                         _("Quantizer:"), 
1931                         x, 
1932                         y, 
1933                         &asset->divx_quantizer);
1934                 divx_quantizer->create_objects();
1935                 add_subwindow(divx_fix_quant =
1936                         new MOVConfigVideoFixQuant(x + 260, 
1937                                 y,
1938                                 &asset->divx_fix_bitrate,
1939                                 0));
1940                 divx_fix_quant->opposite = divx_fix_bitrate;
1941                 divx_fix_bitrate->opposite = divx_fix_quant;
1942                 y += 30;
1943                 divx_rc_period = new MOVConfigVideoNum(this, 
1944                         _("RC Period:"), 
1945                         x, 
1946                         y, 
1947                         &asset->divx_rc_period);
1948                 divx_rc_period->create_objects();
1949                 y += 30;
1950                 divx_rc_reaction_ratio = new MOVConfigVideoNum(this, 
1951                         _("Reaction Ratio:"), 
1952                         x, 
1953                         y, 
1954                         &asset->divx_rc_reaction_ratio);
1955                 divx_rc_reaction_ratio->create_objects();
1956                 y += 30;
1957                 divx_rc_reaction_period = new MOVConfigVideoNum(this, 
1958                         _("Reaction Period:"), 
1959                         x, 
1960                         y, 
1961                         &asset->divx_rc_reaction_period);
1962                 divx_rc_reaction_period->create_objects();
1963                 y += 30;
1964                 divx_max_key_interval = new MOVConfigVideoNum(this, 
1965                         _("Max Key Interval:"), 
1966                         x, 
1967                         y, 
1968                         &asset->divx_max_key_interval);
1969                 divx_max_key_interval->create_objects();
1970                 y += 30;
1971                 divx_max_quantizer = new MOVConfigVideoNum(this, 
1972                         _("Max Quantizer:"), 
1973                         x, 
1974                         y, 
1975                         &asset->divx_max_quantizer);
1976                 divx_max_quantizer->create_objects();
1977                 y += 30;
1978                 divx_min_quantizer = new MOVConfigVideoNum(this, 
1979                         _("Min Quantizer:"), 
1980                         x, 
1981                         y, 
1982                         &asset->divx_min_quantizer);
1983                 divx_min_quantizer->create_objects();
1984                 y += 30;
1985                 divx_quality = new MOVConfigVideoNum(this, 
1986                         _("Quality:"), 
1987                         x, 
1988                         y, 
1989                         &asset->divx_quality);
1990                 divx_quality->create_objects();
1991         }
1992         else
1993         if(!strcmp(vcodec, QUICKTIME_JPEG) ||
1994                 !strcmp(vcodec, QUICKTIME_MJPA))
1995         {
1996                 add_subwindow(jpeg_quality_title = new BC_Title(param_x, param_y, _("Quality:")));
1997                 add_subwindow(jpeg_quality = new BC_ISlider(param_x + 80, 
1998                         param_y,
1999                         0,
2000                         200,
2001                         200,
2002                         0,
2003                         100,
2004                         asset->jpeg_quality,
2005                         0,
2006                         0,
2007                         &asset->jpeg_quality));
2008         }
2015 MOVConfigVideoNum::MOVConfigVideoNum(MOVConfigVideo *popup, char *title_text, int x, int y, int *output)
2016  : BC_TumbleTextBox(popup, 
2017                 (int64_t)*output,
2018                 (int64_t)1,
2019                 (int64_t)25000000,
2020                 x + 130, 
2021                 y, 
2022                 100)
2024         this->popup = popup;
2025         this->title_text = title_text;
2026         this->output = output;
2027         this->x = x;
2028         this->y = y;
2031 MOVConfigVideoNum::MOVConfigVideoNum(MOVConfigVideo *popup, 
2032         char *title_text, 
2033         int x, 
2034         int y, 
2035         int min,
2036         int max,
2037         int *output)
2038  : BC_TumbleTextBox(popup, 
2039                 (int64_t)*output,
2040                 (int64_t)min,
2041                 (int64_t)max,
2042                 x + 130, 
2043                 y, 
2044                 100)
2046         this->popup = popup;
2047         this->title_text = title_text;
2048         this->output = output;
2049         this->x = x;
2050         this->y = y;
2053 MOVConfigVideoNum::~MOVConfigVideoNum()
2055         if(!popup->get_deleting()) delete title;
2058 void MOVConfigVideoNum::create_objects()
2060         popup->add_subwindow(title = new BC_Title(x, y, title_text));
2061         BC_TumbleTextBox::create_objects();
2064 int MOVConfigVideoNum::handle_event()
2066         *output = atol(get_text());
2067         return 1;
2076 MOVConfigVideoCheckBox::MOVConfigVideoCheckBox(char *title_text, int x, int y, int *output)
2077  : BC_CheckBox(x, y, *output, title_text)
2079         this->output = output;
2082 int MOVConfigVideoCheckBox::handle_event()
2084         *output = get_value();
2085         return 1;
2093 MOVConfigVideoFixBitrate::MOVConfigVideoFixBitrate(int x, 
2094         int y,
2095         int *output,
2096         int value)
2097  : BC_Radial(x, 
2098         y, 
2099         *output == value, 
2100         _("Fix bitrate"))
2102         this->output = output;
2103         this->value = value;
2106 int MOVConfigVideoFixBitrate::handle_event()
2108         *output = value;
2109         opposite->update(0);
2110         return 1;
2118 MOVConfigVideoFixQuant::MOVConfigVideoFixQuant(int x, 
2119         int y,
2120         int *output,
2121         int value)
2122  : BC_Radial(x, 
2123         y, 
2124         *output == value, 
2125         _("Fix quantization"))
2127         this->output = output;
2128         this->value = value;
2131 int MOVConfigVideoFixQuant::handle_event()
2133         *output = value;
2134         opposite->update(0);
2135         return 1;
2142 MOVConfigVideoPopup::MOVConfigVideoPopup(MOVConfigVideo *popup, int x, int y)
2143  : BC_PopupTextBox(popup, 
2144                 &popup->compression_items,
2145                 FileMOV::compressiontostr(popup->asset->vcodec),
2146                 x, 
2147                 y, 
2148                 300,
2149                 300)
2151         this->popup = popup;
2154 int MOVConfigVideoPopup::handle_event()
2156         strcpy(popup->asset->vcodec, FileMOV::strtocompression(get_text()));
2157         popup->update_parameters();
2158         return 1;