r854: Merge 2.1:
[cinelerra_cv/ct.git] / cinelerra / filemov.C
blobb3b1c6cb45172063308680f2157d08b7ccdbc98d
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"
16 #include <unistd.h>
17 #include <libdv/dv.h>
19 #if 0
20 N_("MPEG-4")
21 N_("Dual H.264")
22 N_("Dual MPEG-4")
23 N_("H.264")
24 N_("H.263")
25 N_("Microsoft MPEG-4")
26 N_("DV")
27 N_("PNG")
28 N_("PNG with Alpha")
29 N_("Uncompressed RGB")
30 N_("Uncompressed RGBA")
31 N_("YUV 4:2:0 Planar")
32 N_("Component Y'CbCr 8-bit 4:2:2 (yuv2)")
33 N_("Component Y'CbCr 8-bit 4:2:2 (2vuy)")
34 N_("YUV 4:1:1 Packed")
35 N_("Component Y'CbCr 8-bit 4:4:4")
36 N_("Component Y'CbCrA 8-bit 4:4:4:4")
37 N_("Component Y'CbCr 10-bit 4:4:4")
38 N_("JPEG Photo")
39 N_("Motion JPEG A")
42 N_("Twos complement")
43 N_("Unsigned")
44 N_("IMA-4")
45 N_("U-Law")
46 N_("Vorbis")
47 N_("MP3")
48 N_("MPEG-4 Audio")
49 #endif
51 #define DIVX_NAME "MPEG-4"
52 #define HV64_NAME "Dual H.264"
53 #define MP4V_NAME "MPEG-4 Video"
54 #define H264_NAME "H.264"
55 #define H263_NAME "H.263"
56 #define HV60_NAME "Dual MPEG-4"
57 #define DIV3_NAME "Microsoft MPEG-4"
58 #define DV_NAME "DV"
59 #define PNG_NAME "PNG"
60 #define PNGA_NAME "PNG with Alpha"
61 #define RGB_NAME "Uncompressed RGB"
62 #define RGBA_NAME "Uncompressed RGBA"
63 #define YUV420_NAME "YUV 4:2:0 Planar"
64 #define YUV422_NAME "Component Y'CbCr 8-bit 4:2:2 (yuv2)"
65 #define TWOVUY_NAME "Component Y'CbCr 8-bit 4:2:2 (2vuy)"
66 #define YUV411_NAME "YUV 4:1:1 Packed"
67 #define YUV444_NAME "Component Y'CbCr 8-bit 4:4:4"
68 #define YUVA4444_NAME "Component Y'CbCrA 8-bit 4:4:4:4"
69 #define YUV444_10BIT_NAME "Component Y'CbCr 10-bit 4:4:4"
70 #define QTJPEG_NAME "JPEG Photo"
71 #define MJPA_NAME "Motion JPEG A"
73 #define TWOS_NAME "Twos complement"
74 #define RAW_NAME "Unsigned"
75 #define IMA4_NAME "IMA-4"
76 #define ULAW_NAME "U-Law"
77 //#define VORBIS_NAME "Vorbis"
78 #define MP3_NAME "MP3"
79 #define MP4A_NAME "MPEG-4 Audio"
80 #define VORBIS_NAME "OGG Vorbis"
86 FileMOV::FileMOV(Asset *asset, File *file)
87  : FileBase(asset, file)
89         reset_parameters();
90         if(asset->format == FILE_UNKNOWN)
91                 asset->format = FILE_MOV;
92         asset->byte_order = 0;
93         suffix_number = 0;
94         threadframe_lock = new Mutex("FileMOV::threadframe_lock");
97 FileMOV::~FileMOV()
99 SET_TRACE
100         close_file();
101 SET_TRACE
102         delete threadframe_lock;
103 SET_TRACE
106 void FileMOV::get_parameters(BC_WindowBase *parent_window, 
107         Asset *asset, 
108         BC_WindowBase* &format_window,
109         int audio_options,
110         int video_options,
111         int lock_compressor)
113         fix_codecs(asset);
114         if(audio_options)
115         {
116                 MOVConfigAudio *window = new MOVConfigAudio(parent_window, asset);
117                 format_window = window;
118                 window->create_objects();
119                 window->run_window();
120                 delete window;
121         }
122         else
123         if(video_options)
124         {
125                 MOVConfigVideo *window = new MOVConfigVideo(parent_window, 
126                         asset, 
127                         lock_compressor);
128                 format_window = window;
129                 window->create_objects();
130                 window->run_window();
131                 delete window;
132         }
135 void FileMOV::fix_codecs(Asset *asset)
137         if(!strcasecmp(asset->vcodec, QUICKTIME_DV) ||
138            !strcasecmp(asset->vcodec, QUICKTIME_DVSD) ||
139            !strcasecmp(asset->vcodec, QUICKTIME_DVCP))
140         {
141 //        printf("AF: %i, AH: %i, VC: %s\n", asset->format, asset->height, asset->vcodec);
142         if (asset->format == FILE_AVI)
143                 strcpy (asset->vcodec, QUICKTIME_DVSD);
144         else if (asset->format == FILE_MOV && asset->height == 576)
145                 strcpy (asset->vcodec, QUICKTIME_DVCP);
146         else if (asset->format == FILE_MOV && asset->height == 480)
147                 strcpy (asset->vcodec, QUICKTIME_DV);
148         }
151 int FileMOV::check_sig(Asset *asset)
153         return quicktime_check_sig(asset->path);
157 int FileMOV::reset_parameters_derived()
159         fd = 0;
160         prev_track = 0;
161         quicktime_atracks = 0;
162         quicktime_vtracks = 0;
163         depth = 24;
164         threads = 0;
165         frames_correction = 0;
166         samples_correction = 0;
167         temp_float = 0;
168         temp_allocated = 0;
172 // Just create the Quicktime objects since this routine is also called
173 // for reopening.
174 int FileMOV::open_file(int rd, int wr)
177         this->rd = rd;
178         this->wr = wr;
180         if(suffix_number == 0) strcpy(prefix_path, asset->path);
182         if(!(fd = quicktime_open(asset->path, rd, wr)))
183         {
184                 printf(_("FileMOV::open_file %s: No such file or directory\n"), asset->path);
185                 return 1;
186         }
188         quicktime_set_cpus(fd, file->cpus);
190         if(rd) format_to_asset();
192         if(wr) asset_to_format();
194 // Set decoding parameter
195         quicktime_set_parameter(fd, "divx_use_deblocking", &asset->divx_use_deblocking);
197 // Set timecode offset
198         quicktime_set_frame_start(fd, asset->tcstart);
200         return 0;
203 int FileMOV::close_file()
205 //printf("FileMOV::close_file 1 %s\n", asset->path);
206         if(fd)
207         {
208                 if(wr) quicktime_set_framerate(fd, asset->frame_rate);
209                 quicktime_close(fd);
210         }
212 //printf("FileMOV::close_file 1\n");
213         if(threads)
214         {
215                 for(int i = 0; i < file->cpus; i++)
216                 {
217                         threads[i]->stop_encoding();
218                         delete threads[i];
219                 }
220                 delete [] threads;
221                 threads = 0;
222         }
224 //printf("FileMOV::close_file 1\n");
225         threadframes.remove_all_objects();
228         if(temp_float) 
229         {
230                 for(int i = 0; i < asset->channels; i++)
231                         delete [] temp_float[i];
232                 delete [] temp_float;
233         }
235 //printf("FileMOV::close_file 1\n");
236         reset_parameters();
237         FileBase::close_file();
238 //printf("FileMOV::close_file 2\n");
239         return 0;
242 void FileMOV::set_frame_start(int64_t offset)
244         quicktime_set_frame_start(fd, offset);
247 void FileMOV::asset_to_format()
249         if(!fd) return;
251         fix_codecs(asset);
253 // Fix up the Quicktime file.
254         quicktime_set_copyright(fd, _("Made with Cinelerra for Linux"));
255         quicktime_set_info(fd, "Quicktime for Linux");
257         if(asset->audio_data)
258         {
259                 quicktime_atracks = quicktime_set_audio(fd, 
260                                 asset->channels, 
261                                 asset->sample_rate, 
262                                 asset->bits, 
263                                 asset->acodec);
264                 quicktime_set_parameter(fd, "vorbis_vbr", &asset->vorbis_vbr);
265                 quicktime_set_parameter(fd, "vorbis_min_bitrate", &asset->vorbis_min_bitrate);
266                 quicktime_set_parameter(fd, "vorbis_bitrate", &asset->vorbis_bitrate);
267                 quicktime_set_parameter(fd, "vorbis_max_bitrate", &asset->vorbis_max_bitrate);
268                 quicktime_set_parameter(fd, "mp3_bitrate", &asset->mp3_bitrate);
269                 quicktime_set_parameter(fd, "mp4a_bitrate", &asset->mp4a_bitrate);
270         }
272         if(asset->video_data)
273         {
274                 char string[16];
275 // Set up the alpha channel compressors
276                 if(!strcmp(asset->vcodec, MOV_RGBA))
277                 {
278                         strcpy(string, QUICKTIME_RAW);
279                         depth = 32;
280                 }
281                 else
282                 if(!strcmp(asset->vcodec, MOV_PNGA))
283                 {
284                         strcpy(string, QUICKTIME_PNG);
285                         depth = 32;
286                 }
287                 else
288                 if(!strcmp(asset->vcodec, QUICKTIME_YUVA4444))
289                 {
290                         strcpy(string, asset->vcodec);
291                         depth = 32;
292                 }
293                 else
294                 {
295                         strcpy(string, asset->vcodec);
296                         depth = 24;
297                 }
300                 quicktime_vtracks = quicktime_set_video(fd, 
301                                         asset->layers, 
302                                         asset->width, 
303                                         asset->height,
304                                         asset->frame_rate,
305                                         string);
309                 for(int i = 0; i < asset->layers; i++)
310                         quicktime_set_depth(fd, depth, i);
312                 quicktime_set_parameter(fd, "jpeg_quality", &asset->jpeg_quality);
314 // set the compression parameters if there are any
315                 quicktime_set_parameter(fd, "divx_bitrate", &asset->divx_bitrate);
316                 quicktime_set_parameter(fd, "divx_rc_period", &asset->divx_rc_period);
317                 quicktime_set_parameter(fd, "divx_rc_reaction_ratio", &asset->divx_rc_reaction_ratio);
318                 quicktime_set_parameter(fd, "divx_rc_reaction_period", &asset->divx_rc_reaction_period);
319                 quicktime_set_parameter(fd, "divx_max_key_interval", &asset->divx_max_key_interval);
320                 quicktime_set_parameter(fd, "divx_max_quantizer", &asset->divx_max_quantizer);
321                 quicktime_set_parameter(fd, "divx_min_quantizer", &asset->divx_min_quantizer);
322                 quicktime_set_parameter(fd, "divx_quantizer", &asset->divx_quantizer);
323                 quicktime_set_parameter(fd, "divx_quality", &asset->divx_quality);
324                 quicktime_set_parameter(fd, "divx_fix_bitrate", &asset->divx_fix_bitrate);
326                 quicktime_set_parameter(fd, "ffmpeg_bitrate", &asset->ms_bitrate);
327                 quicktime_set_parameter(fd, "ffmpeg_bitrate_tolerance", &asset->ms_bitrate_tolerance);
328                 quicktime_set_parameter(fd, "ffmpeg_interlaced", &asset->ms_interlaced);
329                 quicktime_set_parameter(fd, "ffmpeg_quantizer", &asset->ms_quantization);
330                 quicktime_set_parameter(fd, "ffmpeg_gop_size", &asset->ms_gop_size);
331                 quicktime_set_parameter(fd, "ffmpeg_fix_bitrate", &asset->ms_fix_bitrate);
333                 quicktime_set_parameter(fd, "h264_bitrate", &asset->h264_bitrate);
334                 quicktime_set_parameter(fd, "h264_quantizer", &asset->h264_quantizer);
335                 quicktime_set_parameter(fd, "h264_fix_bitrate", &asset->h264_fix_bitrate);
338         }
340         if(wr && asset->format == FILE_AVI)
341         {
342                 quicktime_set_avi(fd, 1);
343         }
347 void FileMOV::format_to_asset()
349         if(!fd) return;
351         if(quicktime_is_avi(fd)) asset->format = FILE_AVI;
352         asset->audio_data = quicktime_has_audio(fd);
353         if(asset->audio_data)
354         {
355                 asset->channels = 0;
356                 int qt_tracks = quicktime_audio_tracks(fd);
357                 for(int i = 0; i < qt_tracks; i++)
358                         asset->channels += quicktime_track_channels(fd, i);
359         
360                 if(!asset->sample_rate)
361                         asset->sample_rate = quicktime_sample_rate(fd, 0);
362                 asset->bits = quicktime_audio_bits(fd, 0);
363                 asset->audio_length = quicktime_audio_length(fd, 0);
364                 strncpy(asset->acodec, quicktime_audio_compressor(fd, 0), 4);
365         }
367 // determine if the video can be read before declaring video data
368         if(quicktime_has_video(fd) && quicktime_supported_video(fd, 0))
369                         asset->video_data = 1;
371         if(asset->video_data)
372         {
373                 depth = quicktime_video_depth(fd, 0);
374                 asset->layers = quicktime_video_tracks(fd);
375                 asset->width = quicktime_video_width(fd, 0);
376                 asset->height = quicktime_video_height(fd, 0);
377                 asset->video_length = quicktime_video_length(fd, 0);
378 // Don't want a user configured frame rate to get destroyed
379                 if(!asset->frame_rate)
380                         asset->frame_rate = quicktime_frame_rate(fd, 0);
381                 if(!asset->interlace_mode)
382                         asset->interlace_mode = quicktime_video_interlacemode(fd, 0);
384                 strncpy(asset->vcodec, quicktime_video_compressor(fd, 0), 4);
386                 // If DV stream, get the timecode 
387                 // This should become part of libquicktime functionality... for all formats
388                 if(match4(asset->vcodec, QUICKTIME_DV))
389                 {
390                         char tc[12];
391                         dv_decoder_t *tmp_decoder = dv_decoder_new(0,0,0);
392                         VFrame *frame = new VFrame(0, 0, 0, BC_COMPRESSED);
393                         
394                         read_frame(frame);
395                         set_video_position(0);
396                         
397                         if(dv_parse_header(tmp_decoder, frame->get_data()) > -1)
398                         {
399                                 dv_parse_packs(tmp_decoder, frame->get_data());
400                                 dv_get_timestamp(tmp_decoder, tc);
401 //                              printf("Timestamp %s\n", tc);
402                         
403                                 float seconds = Units::text_to_seconds(tc,
404                                                                                 1, // Use 1 as sample rate, doesn't matter
405                                                                                 TIME_HMSF,
406                                                                                 asset->frame_rate,
407                                                                                 0);
408                                 // Set tcstart if it hasn't been set yet, this is a bit problematic
409                                 // 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
410                                 if (asset->tcstart == 0)
411                                         asset->tcstart = int64_t(seconds * asset->frame_rate);
412                         }
413                         delete frame;
414                         dv_decoder_free(tmp_decoder);
415                         
416                 }
419         }
422 int64_t FileMOV::get_memory_usage()
424         if(rd && fd)
425         {
426                 int64_t result = quicktime_memory_usage(fd);
427 //printf("FileMOV::get_memory_usage 1 %d\n", result);
428                 return result;
429         }
430         return 0;
433 int FileMOV::colormodel_supported(int colormodel)
435         return colormodel;
438 int FileMOV::get_best_colormodel(Asset *asset, int driver)
440         switch(driver)
441         {
442                 case PLAYBACK_X11:
443                         return BC_RGB888;
444                         break;
445                 case PLAYBACK_X11_XV:
446                         if(match4(asset->vcodec, QUICKTIME_YUV420)) return BC_YUV420P;
447                         if(match4(asset->vcodec, QUICKTIME_YUV422)) return BC_YUV422;
448                         if(match4(asset->vcodec, QUICKTIME_2VUY)) return BC_YUV422;
449                         if(match4(asset->vcodec, QUICKTIME_JPEG)) return BC_YUV420P;
450                         if(match4(asset->vcodec, QUICKTIME_MJPA)) return BC_YUV422P;
451                         if(match4(asset->vcodec, QUICKTIME_DV)) return BC_YUV422;
452                         if(match4(asset->vcodec, QUICKTIME_DVSD)) return BC_YUV422;
453                         if(match4(asset->vcodec, QUICKTIME_HV60)) return BC_YUV420P;
454                         if(match4(asset->vcodec, QUICKTIME_DIVX)) return BC_YUV420P;
455                         if(match4(asset->vcodec, QUICKTIME_DVCP)) return BC_YUV422;
456                         if(match4(asset->vcodec, QUICKTIME_MP4V)) return BC_YUV420P;
457                         if(match4(asset->vcodec, QUICKTIME_H263)) return BC_YUV420P;
458                         if(match4(asset->vcodec, QUICKTIME_H264)) return BC_YUV420P;
459                         if(match4(asset->vcodec, QUICKTIME_HV64)) return BC_YUV420P;
460                         if(match4(asset->vcodec, QUICKTIME_DIV3)) return BC_YUV420P;
461                         break;
462                 case PLAYBACK_X11_GL:
463                         if(match4(asset->vcodec, QUICKTIME_YUV420) ||
464                                 match4(asset->vcodec, QUICKTIME_YUV422) ||
465                                 match4(asset->vcodec, QUICKTIME_2VUY) ||
466                                 match4(asset->vcodec, QUICKTIME_JPEG) ||
467                                 match4(asset->vcodec, QUICKTIME_MJPA) ||
468                                 match4(asset->vcodec, QUICKTIME_DV) ||
469                                 match4(asset->vcodec, QUICKTIME_DVCP) ||
470                                 match4(asset->vcodec, QUICKTIME_DVSD) ||
471                                 match4(asset->vcodec, QUICKTIME_HV60) ||
472                                 match4(asset->vcodec, QUICKTIME_DIVX) ||
473                                 match4(asset->vcodec, QUICKTIME_DVSD) ||
474                                 match4(asset->vcodec, QUICKTIME_MP4V) ||
475                                 match4(asset->vcodec, QUICKTIME_H263) ||
476                                 match4(asset->vcodec, QUICKTIME_H264) ||
477                                 match4(asset->vcodec, QUICKTIME_HV64) ||
478                                 match4(asset->vcodec, QUICKTIME_DIV3) || 
479                                 match4(asset->vcodec, QUICKTIME_DVSD)) return BC_YUV888;
480                         break;
481                 case PLAYBACK_DV1394:
482                 case PLAYBACK_FIREWIRE:
483                         if(match4(asset->vcodec, QUICKTIME_DV) || 
484                                 match4(asset->vcodec, QUICKTIME_DVSD) ||
485                                 match4(asset->vcodec, QUICKTIME_DVCP)) return BC_COMPRESSED;
486                         return BC_YUV422P;
487                         break;
488                 case PLAYBACK_LML:
489                 case PLAYBACK_BUZ:
490                         if(match4(asset->vcodec, QUICKTIME_MJPA)) 
491                                 return BC_COMPRESSED;
492                         else
493                                 return BC_YUV422P;
494                         break;
495                 case VIDEO4LINUX:
496                 case VIDEO4LINUX2:
497                         if(!strncasecmp(asset->vcodec, QUICKTIME_YUV420, 4)) return BC_YUV422;
498                         else
499                         if(!strncasecmp(asset->vcodec, QUICKTIME_YUV422, 4)) return BC_YUV422;
500                         else
501                         if(!strncasecmp(asset->vcodec, QUICKTIME_2VUY, 4)) return BC_YUV422;
502                         else
503                         if(!strncasecmp(asset->vcodec, QUICKTIME_YUV411, 4)) return BC_YUV411P;
504                         else
505                         if(!strncasecmp(asset->vcodec, QUICKTIME_JPEG, 4)) return BC_YUV420P;
506                         else
507                         if(!strncasecmp(asset->vcodec, QUICKTIME_MJPA, 4)) return BC_YUV422P;
508                         else
509                         if(!strncasecmp(asset->vcodec, QUICKTIME_HV60, 4)) return BC_YUV420P;
510                         else
511                         if(!strncasecmp(asset->vcodec, QUICKTIME_DIVX, 4)) return BC_YUV420P;
512                         else
513                         if(!strncasecmp(asset->vcodec, QUICKTIME_H263, 4)) return BC_YUV420P;
514                         else
515                         if(!strncasecmp(asset->vcodec, QUICKTIME_DIV3, 4)) return BC_YUV420P;
516                         break;
517                 case CAPTURE_BUZ:
518                 case CAPTURE_LML:
519                 case VIDEO4LINUX2JPEG:
520                         if(!strncasecmp(asset->vcodec, QUICKTIME_MJPA, 4)) 
521                                 return BC_COMPRESSED;
522                         else
523                                 return BC_YUV422;
524                         break;
525                 case CAPTURE_FIREWIRE:
526                 case CAPTURE_IEC61883:
527                         if(!strncasecmp(asset->vcodec, QUICKTIME_DV, 4) ||
528                                 !strncasecmp(asset->vcodec, QUICKTIME_DVSD, 4) ||
529                                 !strncasecmp(asset->vcodec, QUICKTIME_DVCP, 4)) 
530                                 return BC_COMPRESSED;
531                         else
532                                 return BC_YUV422;
533                         break;
534         }
535         return BC_RGB888;
538 int FileMOV::can_copy_from(Edit *edit, int64_t position)
540         if(!fd) return 0;
542 //printf("FileMOV::can_copy_from 1 %d %s %s\n", edit->asset->format, edit->asset->vcodec, this->asset->vcodec);
543         if(edit->asset->format == FILE_JPEG_LIST && 
544                 match4(this->asset->vcodec, QUICKTIME_JPEG))
545                 return 1;
546         else
547         if((edit->asset->format == FILE_MOV || 
548                 edit->asset->format == FILE_AVI))
549         {
550 //printf("FileMOV::can_copy_from %s %s\n", edit->asset->vcodec, this->asset->vcodec);
551                 if(match4(edit->asset->vcodec, this->asset->vcodec))
552                         return 1;
553 // there are combinations where the same codec has multiple fourcc codes
554 // check for DV...
555                 int is_edit_dv = 0;
556                 int is_this_dv = 0;
557                 if (match4(edit->asset->vcodec, QUICKTIME_DV) || 
558                         match4(edit->asset->vcodec, QUICKTIME_DVSD) || 
559                         match4(edit->asset->vcodec, QUICKTIME_DVCP))
560                         is_edit_dv = 1;
561                 if (match4(this->asset->vcodec, QUICKTIME_DV) || 
562                         match4(this->asset->vcodec, QUICKTIME_DVSD) || 
563                         match4(this->asset->vcodec, QUICKTIME_DVCP))
564                         is_this_dv = 1;
565                 if (is_this_dv && is_edit_dv)
566                         return 1;
567         }
568         else
569         if(edit->asset->format == FILE_RAWDV)
570         {
571                 if(match4(this->asset->vcodec, QUICKTIME_DV) || 
572                         match4(this->asset->vcodec, QUICKTIME_DVSD) || 
573                         match4(this->asset->vcodec, QUICKTIME_DVCP))
574                         return 1;
575         }
578         return 0;
582 int64_t FileMOV::get_audio_length()
584         if(!fd) return 0;
585         int64_t result = quicktime_audio_length(fd, 0) + samples_correction;
587         return result;
590 int FileMOV::set_audio_position(int64_t x)
592         if(!fd) return 1;
593 // quicktime sets positions for each track seperately so store position in audio_position
594         if(x >= 0 && x < asset->audio_length)
595                 return quicktime_set_audio_position(fd, x, 0);
596         else
597                 return 1;
600 int FileMOV::set_video_position(int64_t x)
602         if(!fd) return 1;
603         if(x >= 0 && x < asset->video_length)
604         {
605                 int result = quicktime_set_video_position(fd, x, file->current_layer);
606                 return result;
607         }else
608                 return 1;
612 void FileMOV::new_audio_temp(int64_t len)
614         if(temp_allocated && temp_allocated < len)
615         {
616                 for(int i = 0; i < asset->channels; i++)
617                         delete [] temp_float[i];
618                 delete [] temp_float;
619                 temp_allocated = 0;
620         }
622         if(!temp_allocated)
623         {
624                 temp_allocated = len;
625                 temp_float = new float*[asset->channels];
626                 for(int i = 0; i < asset->channels; i++)
627                         temp_float[i] = new float[len];
628         }
633 int FileMOV::write_samples(double **buffer, int64_t len)
635         int i, j;
636         int64_t bytes;
637         int result = 0, track_channels = 0;
638         int chunk_size;
640         if(!fd) return 0;
642         if(quicktime_supported_audio(fd, 0))
643         {
644 // Use Quicktime's compressor. (Always used)
645 // Allocate temp buffer
646                 new_audio_temp(len);
648 // Copy to float buffer
649                 for(i = 0; i < asset->channels; i++)
650                 {
651                         for(j = 0; j < len; j++)
652                         {
653                                 temp_float[i][j] = buffer[i][j];
654                         }
655                 }
657 // Because of the way Quicktime's compressors work we want to limit the chunk
658 // size to speed up decompression.
659                 float **channel_ptr;
660                 channel_ptr = new float*[asset->channels];
662                 for(j = 0; j < len && !result; )
663                 {
664                         chunk_size = asset->sample_rate;
665                         if(j + chunk_size > len) chunk_size = len - j;
667                         for(i = 0; i < asset->channels; i++)
668                         {
669                                 channel_ptr[i] = &temp_float[i][j];
670                         }
672                         result = quicktime_encode_audio(fd, 0, channel_ptr, chunk_size);
673                         j += asset->sample_rate;
674                 }
676                 delete [] channel_ptr;
677         }
678         return result;
681 int FileMOV::write_frames(VFrame ***frames, int len)
683 //printf("FileMOV::write_frames 1\n");
684         int i, j, k, result = 0;
685         int default_compressor = 1;
686         if(!fd) return 0;
688         for(i = 0; i < asset->layers && !result; i++)
689         {
695 // Fix direct copy cases for format conversions.
696                 if(frames[i][0]->get_color_model() == BC_COMPRESSED)
697                 {
698                         default_compressor = 0;
699                         for(j = 0; j < len && !result; j++)
700                         {
701                                 VFrame *frame = frames[i][j];
705 // Special handling for DIVX
706 // Determine keyframe status.
707 // Write VOL header in the first frame if none exists
708                                 if(!strcmp(asset->vcodec, QUICKTIME_DIVX) ||
709                                         !strcmp(asset->vcodec, QUICKTIME_H263) ||
710                                         !strcmp(asset->vcodec, QUICKTIME_HV60))
711                                 {
712                                         if(quicktime_mpeg4_is_key(frame->get_data(), 
713                                                 frame->get_compressed_size(),
714                                                 asset->vcodec))
715                                                 quicktime_insert_keyframe(fd, file->current_frame + j, i);
718 // Write header
719                                         if(!(file->current_frame + j) && 
720                                                 !quicktime_mpeg4_has_vol(frame->get_data()))
721                                         {
722                                                 VFrame *temp_frame = new VFrame;
724                                                 temp_frame->allocate_compressed_data(frame->get_compressed_size() + 
725                                                         0xff);
726                                                 int bytes = quicktime_mpeg4_write_vol(temp_frame->get_data(),
727                                                         asset->width, 
728                                                         asset->height, 
729                                                         60000, 
730                                                         asset->frame_rate);
731                                                 memcpy(temp_frame->get_data() + bytes, 
732                                                         frame->get_data(), 
733                                                         frame->get_compressed_size());
734                                                 temp_frame->set_compressed_size(frame->get_compressed_size() + bytes);
736                                                 result = quicktime_write_frame(fd,
737                                                         temp_frame->get_data(),
738                                                         temp_frame->get_compressed_size(),
739                                                         i);
741                                                 delete temp_frame;
744                                         }
745                                         else
746                                         {
747                                                 result = quicktime_write_frame(fd,
748                                                         frame->get_data(),
749                                                         frame->get_compressed_size(),
750                                                         i);
751                                         }
752                                 }
753                                 else
754 // Determine keyframe status
755                                 if(!strcmp(asset->vcodec, QUICKTIME_H264) ||
756                                         !strcmp(asset->vcodec, QUICKTIME_HV64) ||
757                                         !strcmp(asset->vcodec, QUICKTIME_MP4V))
758                                 {
759                                         if(frame->get_keyframe() || file->current_frame + j == 0)
760                                                 quicktime_insert_keyframe(fd, file->current_frame + j, i);
762 // Write frame
763                                                 result = quicktime_write_frame(fd,
764                                                         frame->get_data(),
765                                                         frame->get_compressed_size(),
766                                                         i);
767                                 }
768                                 else
769                                 if(!strcmp(asset->vcodec, QUICKTIME_DIV3))
770                                 {
771                                         if(quicktime_mpeg4_is_key(frame->get_data(), 
772                                                 frame->get_compressed_size(),
773                                                 asset->vcodec))
774                                                 quicktime_insert_keyframe(fd, file->current_frame + j, i);
775                                         result = quicktime_write_frame(fd,
776                                                 frame->get_data(),
777                                                 frame->get_compressed_size(),
778                                                 i);
779                                 }
780                                 else
781                                 if(!strcmp(asset->vcodec, QUICKTIME_MJPA))
782                                 {
783                                         long field2_offset;
785 // Create extra space for markers
786                                         if(frame->get_compressed_allocated() - frame->get_compressed_size() < 0x100)
787                                                 frame->allocate_compressed_data(frame->get_compressed_size() + 0x100);
789                                         unsigned char *data = frame->get_data();
790                                         long data_size = frame->get_compressed_size();
791                                         long data_allocated = frame->get_compressed_allocated();
793 // Sometimes get 0 length frames
794                                         if(data_size)
795                                         {
796                                                 if(asset->format == FILE_MOV)
797                                                 {
798                                                         mjpeg_insert_quicktime_markers(&data,
799                                                                 &data_size,
800                                                                 &data_allocated,
801                                                                 2,
802                                                                 &field2_offset);
803                                                 }
804                                                 else
805                                                 {
806                                                         mjpeg_insert_avi_markers(&data,
807                                                                 &data_size,
808                                                                 &data_allocated,
809                                                                 2,
810                                                                 &field2_offset);
811                                                 }
812                                                 frame->set_compressed_size(data_size);
813                                                 result = quicktime_write_frame(fd,
814                                                         frame->get_data(),
815                                                         frame->get_compressed_size(),
816                                                         i);
817                                         }
818                                         else
819                                                 printf("FileMOV::write_frames data_size=%d\n", data_size);
820                                 }
821                                 else
822                                         result = quicktime_write_frame(fd,
823                                                 frame->get_data(),
824                                                 frame->get_compressed_size(),
825                                                 i);
826                                 
827                                 
828                         }
829                 }
830                 else
831                 if(match4(asset->vcodec, QUICKTIME_YUV420) ||
832                         match4(asset->vcodec, QUICKTIME_2VUY) ||
833                         match4(asset->vcodec, QUICKTIME_YUV422) ||
834                         match4(asset->vcodec, QUICKTIME_RAW))
835                 {
836 // Direct copy planes where possible
837                         default_compressor = 0;
838                         for(j = 0; j < len && !result; j++)
839                         {
840                                 VFrame *frame = frames[i][j];
841 //printf("FileMOV::write_frames 1 %d\n", frame->get_color_model());
842                                 quicktime_set_cmodel(fd, frame->get_color_model());
843                                 if(cmodel_is_planar(frame->get_color_model()))
844                                 {
845                                         unsigned char *planes[3];
846                                         planes[0] = frame->get_y();
847                                         planes[1] = frame->get_u();
848                                         planes[2] = frame->get_v();
849                                         result = quicktime_encode_video(fd, planes, i);
850                                 }
851                                 else
852                                 {
853                                         result = quicktime_encode_video(fd, frame->get_rows(), i);
854 //printf("FileMOV::write_frames 2 %d\n", result);
855                                 }
856 //printf("FileMOV::write_frames 2\n");
857                         }
858                 }
859                 else
860                 if(file->cpus > 1 && 
861                         (match4(asset->vcodec, QUICKTIME_JPEG) || 
862                         match4(asset->vcodec, QUICKTIME_MJPA)))
863                 {
864                         default_compressor = 0;
865 // Compress symmetrically on an SMP system.
866                         ThreadStruct *threadframe;
867                         int fields = match4(asset->vcodec, QUICKTIME_MJPA) ? 2 : 1;
869 // Set up threads for symmetric compression.
870                         if(!threads)
871                         {
872                                 threads = new FileMOVThread*[file->cpus];
873                                 for(j = 0; j < file->cpus; j++)
874                                 {
875                                         threads[j] = new FileMOVThread(this, fields);
876                                         threads[j]->start_encoding();
877                                 }
878                         }
880 // Set up the frame structures for asynchronous compression.
881 // The mjpeg object must exist in each threadframe because it is where the output
882 // is stored.
883                         while(threadframes.total < len)
884                         {
885                                 threadframes.append(threadframe = new ThreadStruct);
886                         }
888 // Load thread frame structures with new frames.
889                         for(j = 0; j < len; j++)
890                         {
891                                 VFrame *frame = frames[i][j];
892                                 threadframes.values[j]->input = frame;
893                                 threadframes.values[j]->completion_lock->lock("FileMOV::write_frames 1");
894                         }
895                         total_threadframes = len;
896                         current_threadframe = 0;
898 // Start the threads compressing
899                         for(j = 0; j < file->cpus; j++)
900                         {
901                                 threads[j]->encode_buffer();
902                         }
905 // Write the frames as they're finished
906                         for(j = 0; j < len; j++)
907                         {
908                                 threadframes.values[j]->completion_lock->lock("FileMOV::write_frames 1");
909                                 threadframes.values[j]->completion_lock->unlock();
910                                 if(!result)
911                                 {
912                                         result = quicktime_write_frame(fd, 
913                                                 threadframes.values[j]->output,
914                                                 threadframes.values[j]->output_size,
915                                                 i);
916                                 }
917                         }
918                 }
920                 if(default_compressor)
921                 {
922 //printf("FileMOV::write_frames 3\n");
923 // Use the library's built in compressor.
924                         for(j = 0; j < len && !result; j++)
925                         {
926 //printf("FileMOV::write_frames 4\n");
927                                 VFrame *frame = frames[i][j];
928                                 quicktime_set_cmodel(fd, frame->get_color_model());
929 //printf("FileMOV::write_frames 5\n");
930                                 if(cmodel_is_planar(frame->get_color_model()))
931                                 {
932                                         unsigned char *planes[3];
933                                         planes[0] = frame->get_y();
934                                         planes[1] = frame->get_u();
935                                         planes[2] = frame->get_v();
936                                         result = quicktime_encode_video(fd, planes, i);
937                                 }
938                                 else
939                                 {
940                                         result = quicktime_encode_video(fd, frame->get_rows(), i);
941                                 }
942                         }
943                 }
944 //printf("FileMOV::write_frames 4\n");
945         }
948 //printf("FileMOV::write_frames 100 %d\n", result);
949         return result;
954 int FileMOV::read_frame(VFrame *frame)
956         if(!fd) return 1;
957         int result = 0;
959         switch(frame->get_color_model())
960         {
961                 case BC_COMPRESSED:
962                         frame->allocate_compressed_data(quicktime_frame_size(fd, file->current_frame, file->current_layer));
963                         frame->set_compressed_size(quicktime_frame_size(fd, file->current_frame, file->current_layer));
964                         frame->set_keyframe((quicktime_get_keyframe_before(fd, 
965                                 file->current_frame, 
966                                 file->current_layer) == file->current_frame));
967 //printf("FileMOV::read_frame 1 %lld %d\n", file->current_frame, frame->get_keyframe());
968                         result = quicktime_read_frame(fd, 
969                                 frame->get_data(), 
970                                 file->current_layer);
971                         break;
973 // Progressive
974                 case BC_YUV420P:
975                 case BC_YUV422P:
976                 {
977                         unsigned char *row_pointers[3];
978                         row_pointers[0] = frame->get_y();
979                         row_pointers[1] = frame->get_u();
980                         row_pointers[2] = frame->get_v();
982                         quicktime_set_cmodel(fd, frame->get_color_model());
983                         quicktime_decode_video(fd, 
984                                 row_pointers,
985                                 file->current_layer);
986                 }
987                         break;
989 // Packed
990                 default:
991                         quicktime_set_cmodel(fd, frame->get_color_model());
992                         result = quicktime_decode_video(fd, 
993                                 frame->get_rows(),
994                                 file->current_layer);
995 //for(int i = 0; i < 10000; i++) frame->get_rows()[0][i] = 0xff;
996                         break;
997         }
1001         return result;
1006 int64_t FileMOV::compressed_frame_size()
1008         if(!fd) return 0;
1009         return quicktime_frame_size(fd, file->current_frame, file->current_layer);
1012 int FileMOV::read_compressed_frame(VFrame *buffer)
1014         int64_t result;
1015         if(!fd) return 0;
1017         result = quicktime_read_frame(fd, buffer->get_data(), file->current_layer);
1018         buffer->set_compressed_size(result);
1019         buffer->set_keyframe((quicktime_get_keyframe_before(fd, 
1020                 file->current_frame, 
1021                 file->current_layer) == file->current_frame));
1022         result = !result;
1023         return result;
1026 int FileMOV::write_compressed_frame(VFrame *buffer)
1028         int result = 0;
1029         if(!fd) return 0;
1031         result = quicktime_write_frame(fd, 
1032                 buffer->get_data(), 
1033                 buffer->get_compressed_size(), 
1034                 file->current_layer);
1035         return result;
1040 int FileMOV::read_raw(VFrame *frame, 
1041                 float in_x1, float in_y1, float in_x2, float in_y2,
1042                 float out_x1, float out_y1, float out_x2, float out_y2, 
1043                 int use_float, int interpolate)
1045         int64_t i, color_channels, result = 0;
1046         if(!fd) return 0;
1048         quicktime_set_video_position(fd, file->current_frame, file->current_layer);
1049 // Develop importing strategy
1050         switch(frame->get_color_model())
1051         {
1052                 case BC_RGB888:
1053                         result = quicktime_decode_video(fd, frame->get_rows(), file->current_layer);
1054                         break;
1055                 case BC_RGBA8888:
1056                         break;
1057                 case BC_RGB161616:
1058                         break;
1059                 case BC_RGBA16161616:
1060                         break;
1061                 case BC_YUV888:
1062                         break;
1063                 case BC_YUVA8888:
1064                         break;
1065                 case BC_YUV161616:
1066                         break;
1067                 case BC_YUVA16161616:
1068                         break;
1069                 case BC_YUV420P:
1070                         break;
1071         }
1072         return result;
1075 // Overlay samples
1076 int FileMOV::read_samples(double *buffer, int64_t len)
1078         int qt_track, qt_channel;
1080         if(!fd) return 0;
1082         if(quicktime_track_channels(fd, 0) > file->current_channel &&
1083                 quicktime_supported_audio(fd, 0))
1084         {
1086 //printf("FileMOV::read_samples 2 %ld %ld\n", file->current_sample, quicktime_audio_position(fd, 0));
1087                 new_audio_temp(len);
1089 //printf("FileMOV::read_samples 3 %ld %ld\n", file->current_sample, quicktime_audio_position(fd, 0));
1090                 if(quicktime_decode_audio(fd, 0, temp_float[0], len, file->current_channel))
1091                 {
1092                         printf("FileMOV::read_samples: quicktime_decode_audio failed\n");
1093                         return 1;
1094                 }
1095                 else
1096                 {
1097                         for(int i = 0; i < len; i++) buffer[i] = temp_float[0][i];
1098                 }
1100 // if(file->current_channel == 0)
1101 // for(int i = 0; i < len; i++)
1102 // {
1103 //      int16_t value;
1104 //      value = (int16_t)(temp_float[0][i] * 32767);
1105 //      fwrite(&value, 2, 1, stdout);
1106 // }
1107 //printf("FileMOV::read_samples 4 %ld %ld\n", file->current_sample, quicktime_audio_position(fd, 0));
1108         }
1110         return 0;
1114 char* FileMOV::strtocompression(char *string)
1116         if(!strcasecmp(string, _(DIVX_NAME))) return QUICKTIME_DIVX;
1117         if(!strcasecmp(string, _(H264_NAME))) return QUICKTIME_H264;
1118         if(!strcasecmp(string, _(HV64_NAME))) return QUICKTIME_HV64;
1119         if(!strcasecmp(string, _(MP4V_NAME))) return QUICKTIME_MP4V;
1120         if(!strcasecmp(string, _(H263_NAME))) return QUICKTIME_H263;
1121         if(!strcasecmp(string, _(HV60_NAME))) return QUICKTIME_HV60;
1122         if(!strcasecmp(string, _(DIV3_NAME))) return QUICKTIME_DIV3;
1123         if(!strcasecmp(string, _(DV_NAME))) return QUICKTIME_DV;
1124         if(!strcasecmp(string, _(PNG_NAME))) return QUICKTIME_PNG;
1125         if(!strcasecmp(string, _(PNGA_NAME))) return MOV_PNGA;
1126         if(!strcasecmp(string, _(RGB_NAME))) return QUICKTIME_RAW;
1127         if(!strcasecmp(string, _(RGBA_NAME))) return MOV_RGBA;
1128         if(!strcasecmp(string, _(QTJPEG_NAME))) return QUICKTIME_JPEG;
1129         if(!strcasecmp(string, _(MJPA_NAME))) return QUICKTIME_MJPA;
1130         if(!strcasecmp(string, _(YUV420_NAME))) return QUICKTIME_YUV420;
1131         if(!strcasecmp(string, _(YUV411_NAME))) return QUICKTIME_YUV411;
1132         if(!strcasecmp(string, _(YUV422_NAME))) return QUICKTIME_YUV422;
1133         if(!strcasecmp(string, _(TWOVUY_NAME))) return QUICKTIME_2VUY;
1134         if(!strcasecmp(string, _(YUV444_NAME))) return QUICKTIME_YUV444;
1135         if(!strcasecmp(string, _(YUVA4444_NAME))) return QUICKTIME_YUVA4444;
1136         if(!strcasecmp(string, _(YUV444_10BIT_NAME))) return QUICKTIME_YUV444_10bit;
1138         if(!strcasecmp(string, _(TWOS_NAME))) return QUICKTIME_TWOS;
1139         if(!strcasecmp(string, _(RAW_NAME))) return QUICKTIME_RAW;
1140         if(!strcasecmp(string, _(IMA4_NAME))) return QUICKTIME_IMA4;
1141         if(!strcasecmp(string, _(ULAW_NAME))) return QUICKTIME_ULAW;
1142         if(!strcasecmp(string, _(MP3_NAME))) return QUICKTIME_MP3;
1143         if(!strcasecmp(string, _(MP4A_NAME))) return QUICKTIME_MP4A;
1144         if(!strcasecmp(string, _(VORBIS_NAME))) return QUICKTIME_VORBIS;
1148         return QUICKTIME_RAW;
1151 char* FileMOV::compressiontostr(char *string)
1153         if(match4(string, QUICKTIME_H263)) return _(H263_NAME);
1154         if(match4(string, QUICKTIME_H264)) return _(H264_NAME);
1155         if(match4(string, QUICKTIME_HV64)) return _(HV64_NAME);
1156         if(match4(string, QUICKTIME_DIVX)) return _(DIVX_NAME);
1157         if(match4(string, QUICKTIME_MP4V)) return _(MP4V_NAME);
1158         if(match4(string, QUICKTIME_HV60)) return _(HV60_NAME);
1159         if(match4(string, QUICKTIME_DIV3)) return _(DIV3_NAME);
1160         if(match4(string, QUICKTIME_DV)) return _(DV_NAME);
1161         if(match4(string, QUICKTIME_DVCP)) return _(DV_NAME);
1162         if(match4(string, QUICKTIME_DVSD)) return _(DV_NAME);
1163         if(match4(string, MOV_PNGA)) return _(PNGA_NAME);
1164         if(match4(string, QUICKTIME_RAW)) return _(RGB_NAME);
1165         if(match4(string, MOV_RGBA)) return _(RGBA_NAME);
1166         if(match4(string, QUICKTIME_JPEG)) return _(QTJPEG_NAME);
1167         if(match4(string, QUICKTIME_MJPA)) return _(MJPA_NAME);
1168         if(match4(string, QUICKTIME_YUV420)) return _(YUV420_NAME);
1169         if(match4(string, QUICKTIME_YUV411)) return _(YUV411_NAME);
1170         if(match4(string, QUICKTIME_YUV422)) return _(YUV422_NAME);
1171         if(match4(string, QUICKTIME_2VUY)) return _(TWOVUY_NAME);
1172         if(match4(string, QUICKTIME_YUV444)) return _(YUV444_NAME);
1173         if(match4(string, QUICKTIME_YUVA4444)) return _(YUVA4444_NAME);
1174         if(match4(string, QUICKTIME_YUV444_10bit)) return _(YUV444_10BIT_NAME);
1180         if(match4(string, QUICKTIME_TWOS)) return _(TWOS_NAME);
1181         if(match4(string, QUICKTIME_RAW)) return _(RAW_NAME);
1182         if(match4(string, QUICKTIME_IMA4)) return _(IMA4_NAME);
1183         if(match4(string, QUICKTIME_ULAW)) return _(ULAW_NAME);
1184         if(match4(string, QUICKTIME_MP3)) return _(MP3_NAME);
1185         if(match4(string, QUICKTIME_MP4A)) return _(MP4A_NAME);
1186         if(match4(string, QUICKTIME_VORBIS)) return _(VORBIS_NAME);
1190         return _("Unknown");
1197 ThreadStruct::ThreadStruct()
1199         input = 0;
1200         output = 0;
1201         output_allocated = 0;
1202         output_size = 0;
1203         completion_lock = new Condition(1, "ThreadStruct::completion_lock");
1206 ThreadStruct::~ThreadStruct()
1208         if(output) delete [] output;
1209         delete completion_lock;
1212 void ThreadStruct::load_output(mjpeg_t *mjpeg)
1214         if(output_allocated < mjpeg_output_size(mjpeg))
1215         {
1216                 delete [] output;
1217                 output = 0;
1218         }
1219         if(!output)
1220         {
1221                 output_allocated = mjpeg_output_size(mjpeg);
1222                 output = new unsigned char[output_allocated];
1223         }
1224         
1225         output_size = mjpeg_output_size(mjpeg);
1226         memcpy(output, mjpeg_output_buffer(mjpeg), output_size);
1230 FileMOVThread::FileMOVThread(FileMOV *filemov, int fields) : Thread()
1232         this->filemov = filemov;
1233         this->fields = fields;
1234         mjpeg = 0;
1235         input_lock = new Condition(1, "FileMOVThread::input_lock");
1238 FileMOVThread::~FileMOVThread()
1240         delete input_lock;
1243 int FileMOVThread::start_encoding()
1245         mjpeg = mjpeg_new(filemov->asset->width, 
1246                 filemov->asset->height, 
1247                 fields);
1248         mjpeg_set_quality(mjpeg, filemov->asset->jpeg_quality);
1249         mjpeg_set_float(mjpeg, 0);
1250         done = 0;
1251         set_synchronous(1);
1252         input_lock->lock("FileMOVThread::start_encoding");
1253         start();
1256 int FileMOVThread::stop_encoding()
1258         done = 1;
1259         input_lock->unlock();
1260         join();
1261         if(mjpeg) mjpeg_delete(mjpeg);
1264 int FileMOVThread::encode_buffer()
1266         input_lock->unlock();
1269 void FileMOVThread::run()
1271         while(!done)
1272         {
1273                 input_lock->lock("FileMOVThread::run");
1275                 if(!done)
1276                 {
1277 // Get a frame to compress.
1278                         filemov->threadframe_lock->lock("FileMOVThread::stop_encoding");
1279                         if(filemov->current_threadframe < filemov->total_threadframes)
1280                         {
1281 // Frame is available to process.
1282                                 input_lock->unlock();
1283                                 threadframe = filemov->threadframes.values[filemov->current_threadframe];
1284                                 VFrame *frame = threadframe->input;
1286                                 filemov->current_threadframe++;
1287                                 filemov->threadframe_lock->unlock();
1289                                 mjpeg_compress(mjpeg, 
1290                                         frame->get_rows(), 
1291                                         frame->get_y(), 
1292                                         frame->get_u(), 
1293                                         frame->get_v(),
1294                                         frame->get_color_model(),
1295                                         1);
1297                                 if(fields > 1)
1298                                 {
1299                                         unsigned char *data = mjpeg_output_buffer(mjpeg);
1300                                         long data_size = mjpeg_output_size(mjpeg);
1301                                         long data_allocated = mjpeg_output_allocated(mjpeg);
1302                                         long field2_offset;
1304                                         if(filemov->asset->format == FILE_MOV)
1305                                         {
1306                                                 mjpeg_insert_quicktime_markers(&data,
1307                                                         &data_size,
1308                                                         &data_allocated,
1309                                                         2,
1310                                                         &field2_offset);
1311                                         }
1312                                         else
1313                                         {
1314                                                 mjpeg_insert_avi_markers(&data,
1315                                                         &data_size,
1316                                                         &data_allocated,
1317                                                         2,
1318                                                         &field2_offset);
1319                                         }
1320                                         mjpeg_set_output_size(mjpeg, data_size);
1321                                 }
1322                                 threadframe->load_output(mjpeg);
1323                                 threadframe->completion_lock->unlock();
1324                         }
1325                         else
1326                                 filemov->threadframe_lock->unlock();
1327                 }
1328         }
1336 MOVConfigAudio::MOVConfigAudio(BC_WindowBase *parent_window, Asset *asset)
1337  : BC_Window(PROGRAM_NAME ": Audio Compression",
1338         parent_window->get_abs_cursor_x(1),
1339         parent_window->get_abs_cursor_y(1),
1340         350,
1341         250)
1343         this->parent_window = parent_window;
1344         this->asset = asset;
1345         compression_popup = 0;
1346         reset();
1349 MOVConfigAudio::~MOVConfigAudio()
1351         if(compression_popup) delete compression_popup;
1352         if(bits_popup) delete bits_popup;
1353         compression_items.remove_all_objects();
1357 void MOVConfigAudio::reset()
1359         bits_popup = 0;
1360         bits_title = 0;
1361         dither = 0;
1362         vorbis_min_bitrate = 0;
1363         vorbis_bitrate = 0;
1364         vorbis_max_bitrate = 0;
1365         vorbis_vbr = 0;
1366         mp3_bitrate = 0;
1367         mp4a_bitrate = 0;
1368         mp4a_quantqual = 0;
1371 int MOVConfigAudio::create_objects()
1373         int x = 10, y = 10;
1376         if(asset->format == FILE_MOV)
1377         {
1378                 compression_items.append(new BC_ListBoxItem(_(TWOS_NAME)));
1379                 compression_items.append(new BC_ListBoxItem(_(RAW_NAME)));
1380                 compression_items.append(new BC_ListBoxItem(_(IMA4_NAME)));
1381                 compression_items.append(new BC_ListBoxItem(_(MP3_NAME)));
1382                 compression_items.append(new BC_ListBoxItem(_(ULAW_NAME)));
1383                 compression_items.append(new BC_ListBoxItem(_(VORBIS_NAME)));
1384                 compression_items.append(new BC_ListBoxItem(_(MP4A_NAME)));
1385         }
1386         else
1387         {
1388                 compression_items.append(new BC_ListBoxItem(_(TWOS_NAME)));
1389                 compression_items.append(new BC_ListBoxItem(_(MP3_NAME)));
1390                 compression_items.append(new BC_ListBoxItem(_(VORBIS_NAME)));
1391                 compression_items.append(new BC_ListBoxItem(_(MP4A_NAME)));
1392         }
1394         add_tool(new BC_Title(x, y, _("Compression:")));
1395         y += 25;
1396         compression_popup = new MOVConfigAudioPopup(this, x, y);
1397         compression_popup->create_objects();
1399         update_parameters();
1401         add_subwindow(new BC_OKButton(this));
1402         return 0;
1405 void MOVConfigAudio::update_parameters()
1407         int x = 10, y = 70;
1408         if(bits_title) delete bits_title;
1409         if(bits_popup) delete bits_popup;
1410         if(dither) delete dither;
1411         if(vorbis_min_bitrate) delete vorbis_min_bitrate;
1412         if(vorbis_bitrate) delete vorbis_bitrate;
1413         if(vorbis_max_bitrate) delete vorbis_max_bitrate;
1414         if(vorbis_vbr) delete vorbis_vbr;
1415         if(mp3_bitrate) delete mp3_bitrate;
1416         delete mp4a_bitrate;
1417         delete mp4a_quantqual;
1419         reset();
1423         if(!strcasecmp(asset->acodec, QUICKTIME_TWOS) ||
1424                 !strcasecmp(asset->acodec, QUICKTIME_RAW))
1425         {
1426                 add_subwindow(bits_title = new BC_Title(x, y, _("Bits per channel:")));
1427                 bits_popup = new BitsPopup(this, 
1428                         x + 150, 
1429                         y, 
1430                         &asset->bits, 
1431                         0, 
1432                         0, 
1433                         0, 
1434                         0, 
1435                         0);
1436                 bits_popup->create_objects();
1437                 y += 40;
1438                 add_subwindow(dither = new BC_CheckBox(x, y, &asset->dither, _("Dither")));
1439         }
1440         else
1441         if(!strcasecmp(asset->acodec, QUICKTIME_IMA4))
1442         {
1443         }
1444         else
1445         if(!strcasecmp(asset->acodec, QUICKTIME_MP3))
1446         {
1447                 mp3_bitrate = new MOVConfigAudioNum(this, 
1448                         _("Bitrate:"), 
1449                         x, 
1450                         y, 
1451                         &asset->mp3_bitrate);
1452                 mp3_bitrate->set_increment(1000);
1453                 mp3_bitrate->create_objects();
1454         }
1455         else
1456         if(!strcasecmp(asset->acodec, QUICKTIME_ULAW))
1457         {
1458         }
1459         else
1460         if(!strcasecmp(asset->acodec, QUICKTIME_VORBIS))
1461         {
1462                 add_subwindow(vorbis_vbr = new MOVConfigAudioToggle(this,
1463                         _("Variable bitrate"),
1464                         x,
1465                         y,
1466                         &asset->vorbis_vbr));
1467                 y += 35;
1468                 vorbis_min_bitrate = new MOVConfigAudioNum(this, 
1469                         _("Min bitrate:"), 
1470                         x, 
1471                         y, 
1472                         &asset->vorbis_min_bitrate);
1473                 vorbis_min_bitrate->set_increment(1000);
1474                 y += 30;
1475                 vorbis_bitrate = new MOVConfigAudioNum(this, 
1476                         _("Avg bitrate:"), 
1477                         x, 
1478                         y, 
1479                         &asset->vorbis_bitrate);
1480                 vorbis_bitrate->set_increment(1000);
1481                 y += 30;
1482                 vorbis_max_bitrate = new MOVConfigAudioNum(this, 
1483                         _("Max bitrate:"), 
1484                         x, 
1485                         y, 
1486                         &asset->vorbis_max_bitrate);
1487                 vorbis_max_bitrate->set_increment(1000);
1491                 vorbis_min_bitrate->create_objects();
1492                 vorbis_bitrate->create_objects();
1493                 vorbis_max_bitrate->create_objects();
1494         }
1495         else
1496         if(!strcasecmp(asset->acodec, QUICKTIME_MP4A))
1497         {
1498                 mp4a_bitrate = new MOVConfigAudioNum(this, 
1499                         _("Bitrate:"), 
1500                         x, 
1501                         y, 
1502                         &asset->mp4a_bitrate);
1503                 mp4a_bitrate->set_increment(1000);
1504                 mp4a_bitrate->create_objects();
1506                 y += 30;
1507                 mp4a_quantqual = new MOVConfigAudioNum(this, 
1508                         _("Quantization Quality (%):"), 
1509                         x, 
1510                         y, 
1511                         &asset->mp4a_quantqual);
1512                 mp4a_quantqual->set_increment(1);
1513                 mp4a_quantqual->create_objects();
1514         }
1517 int MOVConfigAudio::close_event()
1519         set_done(0);
1520         return 1;
1527 MOVConfigAudioToggle::MOVConfigAudioToggle(MOVConfigAudio *popup,
1528         char *title_text,
1529         int x,
1530         int y,
1531         int *output)
1532  : BC_CheckBox(x, y, *output, title_text)
1534         this->popup = popup;
1535         this->output = output;
1537 int MOVConfigAudioToggle::handle_event()
1539         *output = get_value();
1540         return 1;
1547 MOVConfigAudioNum::MOVConfigAudioNum(MOVConfigAudio *popup, char *title_text, int x, int y, int *output)
1548  : BC_TumbleTextBox(popup, 
1549                 (int64_t)*output,
1550                 (int64_t)-1,
1551                 (int64_t)25000000,
1552                 popup->get_w() - 150, 
1553                 y, 
1554                 100)
1556         this->popup = popup;
1557         this->title_text = title_text;
1558         this->output = output;
1559         this->x = x;
1560         this->y = y;
1563 MOVConfigAudioNum::~MOVConfigAudioNum()
1565         if(!popup->get_deleting()) delete title;
1568 void MOVConfigAudioNum::create_objects()
1570         popup->add_subwindow(title = new BC_Title(x, y, title_text));
1571         BC_TumbleTextBox::create_objects();
1574 int MOVConfigAudioNum::handle_event()
1576         *output = atol(get_text());
1577         return 1;
1587 MOVConfigAudioPopup::MOVConfigAudioPopup(MOVConfigAudio *popup, int x, int y)
1588  : BC_PopupTextBox(popup, 
1589                 &popup->compression_items,
1590                 FileMOV::compressiontostr(popup->asset->acodec),
1591                 x, 
1592                 y, 
1593                 300,
1594                 300)
1596         this->popup = popup;
1599 int MOVConfigAudioPopup::handle_event()
1601         strcpy(popup->asset->acodec, FileMOV::strtocompression(get_text()));
1602         popup->update_parameters();
1603         return 1;
1622 MOVConfigVideo::MOVConfigVideo(BC_WindowBase *parent_window, 
1623         Asset *asset, 
1624         int lock_compressor)
1625  : BC_Window(PROGRAM_NAME ": Video Compression",
1626         parent_window->get_abs_cursor_x(1),
1627         parent_window->get_abs_cursor_y(1),
1628         420,
1629         420)
1631         this->parent_window = parent_window;
1632         this->asset = asset;
1633         this->lock_compressor = lock_compressor;
1634         compression_popup = 0;
1636         reset();
1639 MOVConfigVideo::~MOVConfigVideo()
1641         if(compression_popup) delete compression_popup;
1642         compression_items.remove_all_objects();
1645 int MOVConfigVideo::create_objects()
1647         int x = 10, y = 10;
1649         if(asset->format == FILE_MOV)
1650         {
1651                 compression_items.append(new BC_ListBoxItem(_(H264_NAME)));
1652                 compression_items.append(new BC_ListBoxItem(_(HV64_NAME)));
1653 //              compression_items.append(new BC_ListBoxItem(_(DIVX_NAME)));
1654                 compression_items.append(new BC_ListBoxItem(_(MP4V_NAME)));
1655                 compression_items.append(new BC_ListBoxItem(_(HV60_NAME)));
1656                 compression_items.append(new BC_ListBoxItem(_(DIV3_NAME)));
1657                 compression_items.append(new BC_ListBoxItem(_(DV_NAME)));
1658                 compression_items.append(new BC_ListBoxItem(_(QTJPEG_NAME)));
1659                 compression_items.append(new BC_ListBoxItem(_(MJPA_NAME)));
1660                 compression_items.append(new BC_ListBoxItem(_(PNG_NAME)));
1661                 compression_items.append(new BC_ListBoxItem(_(PNGA_NAME)));
1662                 compression_items.append(new BC_ListBoxItem(_(RGB_NAME)));
1663                 compression_items.append(new BC_ListBoxItem(_(RGBA_NAME)));
1664                 compression_items.append(new BC_ListBoxItem(_(YUV420_NAME)));
1665                 compression_items.append(new BC_ListBoxItem(_(YUV422_NAME)));
1666                 compression_items.append(new BC_ListBoxItem(_(TWOVUY_NAME)));
1667                 compression_items.append(new BC_ListBoxItem(_(YUV444_NAME)));
1668                 compression_items.append(new BC_ListBoxItem(_(YUVA4444_NAME)));
1669                 compression_items.append(new BC_ListBoxItem(_(YUV444_10BIT_NAME)));
1670         }
1671         else
1672         {
1673                 compression_items.append(new BC_ListBoxItem(_(H264_NAME)));
1674                 compression_items.append(new BC_ListBoxItem(_(HV64_NAME)));
1675 //              compression_items.append(new BC_ListBoxItem(_(DIVX_NAME)));
1676                 compression_items.append(new BC_ListBoxItem(_(MP4V_NAME)));
1677                 compression_items.append(new BC_ListBoxItem(_(HV60_NAME)));
1678                 compression_items.append(new BC_ListBoxItem(_(DIV3_NAME)));
1679                 compression_items.append(new BC_ListBoxItem(_(DV_NAME)));
1680                 compression_items.append(new BC_ListBoxItem(_(QTJPEG_NAME)));
1681                 compression_items.append(new BC_ListBoxItem(_(MJPA_NAME)));
1682                 compression_items.append(new BC_ListBoxItem(_(PNG_NAME)));
1683         }
1685         add_subwindow(new BC_Title(x, y, _("Compression:")));
1686         y += 25;
1688         if(!lock_compressor)
1689         {
1690                 compression_popup = new MOVConfigVideoPopup(this, x, y);
1691                 compression_popup->create_objects();
1692         }
1693         else
1694         {
1695                 add_subwindow(new BC_Title(x, 
1696                         y, 
1697                         FileMOV::compressiontostr(asset->vcodec),
1698                         MEDIUMFONT,
1699                         RED,
1700                         0));
1701         }
1702         y += 40;
1704         param_x = x;
1705         param_y = y;
1706         update_parameters();
1708         add_subwindow(new BC_OKButton(this));
1709         return 0;
1712 int MOVConfigVideo::close_event()
1714         set_done(0);
1715         return 1;
1719 void MOVConfigVideo::reset()
1721         jpeg_quality = 0;
1722         jpeg_quality_title = 0;
1724         divx_bitrate = 0;
1725         divx_rc_period = 0;
1726         divx_rc_reaction_ratio = 0;
1727         divx_rc_reaction_period = 0;
1728         divx_max_key_interval = 0;
1729         divx_max_quantizer = 0;
1730         divx_min_quantizer = 0;
1731         divx_quantizer = 0;
1732         divx_quality = 0;
1733         divx_fix_bitrate = 0;
1734         divx_fix_quant = 0;
1736         h264_bitrate = 0;
1737         h264_quantizer = 0;
1738         h264_fix_bitrate = 0;
1739         h264_fix_quant = 0;
1741         ms_bitrate = 0;
1742         ms_bitrate_tolerance = 0;
1743         ms_quantization = 0;
1744         ms_interlaced = 0;
1745         ms_gop_size = 0;
1746         ms_fix_bitrate = 0;
1747         ms_fix_quant = 0;
1750 void MOVConfigVideo::update_parameters()
1752         if(jpeg_quality)
1753         {
1754                 delete jpeg_quality_title;
1755                 delete jpeg_quality;
1756         }
1758         if(divx_bitrate) delete divx_bitrate;
1759         if(divx_rc_period) delete divx_rc_period;
1760         if(divx_rc_reaction_ratio) delete divx_rc_reaction_ratio;
1761         if(divx_rc_reaction_period) delete divx_rc_reaction_period;
1762         if(divx_max_key_interval) delete divx_max_key_interval;
1763         if(divx_max_quantizer) delete divx_max_quantizer;
1764         if(divx_min_quantizer) delete divx_min_quantizer;
1765         if(divx_quantizer) delete divx_quantizer;
1766         if(divx_quality) delete divx_quality;
1767         if(divx_fix_quant) delete divx_fix_quant;
1768         if(divx_fix_bitrate) delete divx_fix_bitrate;
1770         if(ms_bitrate) delete ms_bitrate;
1771         if(ms_bitrate_tolerance) delete ms_bitrate_tolerance;
1772         if(ms_interlaced) delete ms_interlaced;
1773         if(ms_quantization) delete ms_quantization;
1774         if(ms_gop_size) delete ms_gop_size;
1775         if(ms_fix_bitrate) delete ms_fix_bitrate;
1776         if(ms_fix_quant) delete ms_fix_quant;
1778         delete h264_bitrate;
1779         delete h264_quantizer;
1780         delete h264_fix_bitrate;
1781         delete h264_fix_quant;
1783         reset();
1786         char *vcodec = asset->vcodec;
1789 // H264 parameters
1790         if(!strcmp(vcodec, QUICKTIME_H264) ||
1791                 !strcmp(vcodec, QUICKTIME_HV64))
1792         {
1793                 int x = param_x, y = param_y;
1794                 h264_bitrate = new MOVConfigVideoNum(this, 
1795                         _("Bitrate:"), 
1796                         x, 
1797                         y, 
1798                         &asset->h264_bitrate);
1799                 h264_bitrate->set_increment(1000000);
1800                 h264_bitrate->create_objects();
1801                 add_subwindow(h264_fix_bitrate = new MOVConfigVideoFixBitrate(x + 260, 
1802                                 y,
1803                                 &asset->h264_fix_bitrate,
1804                                 1));
1805                 y += 30;
1806                 h264_quantizer = new MOVConfigVideoNum(this, 
1807                         _("Quantization:"), 
1808                         x, 
1809                         y, 
1810                         0,
1811                         51,
1812                         &asset->h264_quantizer);
1813                 h264_quantizer->create_objects();
1814                 add_subwindow(h264_fix_quant = new MOVConfigVideoFixQuant(x + 260, 
1815                                 y,
1816                                 &asset->h264_fix_bitrate,
1817                                 0));
1818                 h264_fix_bitrate->opposite = h264_fix_quant;
1819                 h264_fix_quant->opposite = h264_fix_bitrate;
1820         }
1821         else
1822 // ffmpeg parameters
1823         if(!strcmp(vcodec, QUICKTIME_MP4V) ||
1824                 !strcmp(vcodec, QUICKTIME_DIV3))
1825         {
1826                 int x = param_x, y = param_y;
1827                 ms_bitrate = new MOVConfigVideoNum(this, 
1828                         _("Bitrate:"), 
1829                         x, 
1830                         y, 
1831                         &asset->ms_bitrate);
1832                 ms_bitrate->set_increment(1000000);
1833                 ms_bitrate->create_objects();
1834                 add_subwindow(ms_fix_bitrate = new MOVConfigVideoFixBitrate(x + 260, 
1835                                 y,
1836                                 &asset->ms_fix_bitrate,
1837                                 1));
1838                 y += 30;
1840                 ms_bitrate_tolerance = new MOVConfigVideoNum(this, 
1841                         _("Bitrate tolerance:"), 
1842                         x, 
1843                         y, 
1844                         &asset->ms_bitrate_tolerance);
1845                 ms_bitrate_tolerance->create_objects();
1846                 y += 30;
1847                 ms_quantization = new MOVConfigVideoNum(this, 
1848                         _("Quantization:"), 
1849                         x, 
1850                         y, 
1851                         &asset->ms_quantization);
1852                 ms_quantization->create_objects();
1853                 add_subwindow(ms_fix_quant = new MOVConfigVideoFixQuant(x + 260, 
1854                                 y,
1855                                 &asset->ms_fix_bitrate,
1856                                 0));
1857                 ms_fix_bitrate->opposite = ms_fix_quant;
1858                 ms_fix_quant->opposite = ms_fix_bitrate;
1861                 y += 30;
1862                 add_subwindow(ms_interlaced = new MOVConfigVideoCheckBox(_("Interlaced"), 
1863                         x, 
1864                         y, 
1865                         &asset->ms_interlaced));
1866                 y += 30;
1867                 ms_gop_size = new MOVConfigVideoNum(this, 
1868                         _("Keyframe interval:"), 
1869                         x, 
1870                         y, 
1871                         &asset->ms_gop_size);
1872                 ms_gop_size->create_objects();
1873         }
1874         else
1875 // OpenDivx parameters
1876         if(!strcmp(vcodec, QUICKTIME_DIVX) ||
1877                 !strcmp(vcodec, QUICKTIME_H263) ||
1878                 !strcmp(vcodec, QUICKTIME_HV60))
1879         {
1880                 int x = param_x, y = param_y;
1881                 divx_bitrate = new MOVConfigVideoNum(this, 
1882                         _("Bitrate:"), 
1883                         x, 
1884                         y, 
1885                         &asset->divx_bitrate);
1886                 divx_bitrate->set_increment(1000000);
1887                 divx_bitrate->create_objects();
1888                 add_subwindow(divx_fix_bitrate = 
1889                         new MOVConfigVideoFixBitrate(x + 260, 
1890                                 y,
1891                                 &asset->divx_fix_bitrate,
1892                                 1));
1893                 y += 30;
1894                 divx_quantizer = new MOVConfigVideoNum(this, 
1895                         _("Quantizer:"), 
1896                         x, 
1897                         y, 
1898                         &asset->divx_quantizer);
1899                 divx_quantizer->create_objects();
1900                 add_subwindow(divx_fix_quant =
1901                         new MOVConfigVideoFixQuant(x + 260, 
1902                                 y,
1903                                 &asset->divx_fix_bitrate,
1904                                 0));
1905                 divx_fix_quant->opposite = divx_fix_bitrate;
1906                 divx_fix_bitrate->opposite = divx_fix_quant;
1907                 y += 30;
1908                 divx_rc_period = new MOVConfigVideoNum(this, 
1909                         _("RC Period:"), 
1910                         x, 
1911                         y, 
1912                         &asset->divx_rc_period);
1913                 divx_rc_period->create_objects();
1914                 y += 30;
1915                 divx_rc_reaction_ratio = new MOVConfigVideoNum(this, 
1916                         _("Reaction Ratio:"), 
1917                         x, 
1918                         y, 
1919                         &asset->divx_rc_reaction_ratio);
1920                 divx_rc_reaction_ratio->create_objects();
1921                 y += 30;
1922                 divx_rc_reaction_period = new MOVConfigVideoNum(this, 
1923                         _("Reaction Period:"), 
1924                         x, 
1925                         y, 
1926                         &asset->divx_rc_reaction_period);
1927                 divx_rc_reaction_period->create_objects();
1928                 y += 30;
1929                 divx_max_key_interval = new MOVConfigVideoNum(this, 
1930                         _("Max Key Interval:"), 
1931                         x, 
1932                         y, 
1933                         &asset->divx_max_key_interval);
1934                 divx_max_key_interval->create_objects();
1935                 y += 30;
1936                 divx_max_quantizer = new MOVConfigVideoNum(this, 
1937                         _("Max Quantizer:"), 
1938                         x, 
1939                         y, 
1940                         &asset->divx_max_quantizer);
1941                 divx_max_quantizer->create_objects();
1942                 y += 30;
1943                 divx_min_quantizer = new MOVConfigVideoNum(this, 
1944                         _("Min Quantizer:"), 
1945                         x, 
1946                         y, 
1947                         &asset->divx_min_quantizer);
1948                 divx_min_quantizer->create_objects();
1949                 y += 30;
1950                 divx_quality = new MOVConfigVideoNum(this, 
1951                         _("Quality:"), 
1952                         x, 
1953                         y, 
1954                         &asset->divx_quality);
1955                 divx_quality->create_objects();
1956         }
1957         else
1958         if(!strcmp(vcodec, QUICKTIME_JPEG) ||
1959                 !strcmp(vcodec, QUICKTIME_MJPA))
1960         {
1961                 add_subwindow(jpeg_quality_title = new BC_Title(param_x, param_y, _("Quality:")));
1962                 add_subwindow(jpeg_quality = new BC_ISlider(param_x + 80, 
1963                         param_y,
1964                         0,
1965                         200,
1966                         200,
1967                         0,
1968                         100,
1969                         asset->jpeg_quality,
1970                         0,
1971                         0,
1972                         &asset->jpeg_quality));
1973         }
1980 MOVConfigVideoNum::MOVConfigVideoNum(MOVConfigVideo *popup, char *title_text, int x, int y, int *output)
1981  : BC_TumbleTextBox(popup, 
1982                 (int64_t)*output,
1983                 (int64_t)1,
1984                 (int64_t)25000000,
1985                 x + 130, 
1986                 y, 
1987                 100)
1989         this->popup = popup;
1990         this->title_text = title_text;
1991         this->output = output;
1992         this->x = x;
1993         this->y = y;
1996 MOVConfigVideoNum::MOVConfigVideoNum(MOVConfigVideo *popup, 
1997         char *title_text, 
1998         int x, 
1999         int y, 
2000         int min,
2001         int max,
2002         int *output)
2003  : BC_TumbleTextBox(popup, 
2004                 (int64_t)*output,
2005                 (int64_t)min,
2006                 (int64_t)max,
2007                 x + 130, 
2008                 y, 
2009                 100)
2011         this->popup = popup;
2012         this->title_text = title_text;
2013         this->output = output;
2014         this->x = x;
2015         this->y = y;
2018 MOVConfigVideoNum::~MOVConfigVideoNum()
2020         if(!popup->get_deleting()) delete title;
2023 void MOVConfigVideoNum::create_objects()
2025         popup->add_subwindow(title = new BC_Title(x, y, title_text));
2026         BC_TumbleTextBox::create_objects();
2029 int MOVConfigVideoNum::handle_event()
2031         *output = atol(get_text());
2032         return 1;
2041 MOVConfigVideoCheckBox::MOVConfigVideoCheckBox(char *title_text, int x, int y, int *output)
2042  : BC_CheckBox(x, y, *output, title_text)
2044         this->output = output;
2047 int MOVConfigVideoCheckBox::handle_event()
2049         *output = get_value();
2050         return 1;
2058 MOVConfigVideoFixBitrate::MOVConfigVideoFixBitrate(int x, 
2059         int y,
2060         int *output,
2061         int value)
2062  : BC_Radial(x, 
2063         y, 
2064         *output == value, 
2065         _("Fix bitrate"))
2067         this->output = output;
2068         this->value = value;
2071 int MOVConfigVideoFixBitrate::handle_event()
2073         *output = value;
2074         opposite->update(0);
2075         return 1;
2083 MOVConfigVideoFixQuant::MOVConfigVideoFixQuant(int x, 
2084         int y,
2085         int *output,
2086         int value)
2087  : BC_Radial(x, 
2088         y, 
2089         *output == value, 
2090         _("Fix quantization"))
2092         this->output = output;
2093         this->value = value;
2096 int MOVConfigVideoFixQuant::handle_event()
2098         *output = value;
2099         opposite->update(0);
2100         return 1;
2107 MOVConfigVideoPopup::MOVConfigVideoPopup(MOVConfigVideo *popup, int x, int y)
2108  : BC_PopupTextBox(popup, 
2109                 &popup->compression_items,
2110                 FileMOV::compressiontostr(popup->asset->vcodec),
2111                 x, 
2112                 y, 
2113                 300,
2114                 300)
2116         this->popup = popup;
2119 int MOVConfigVideoPopup::handle_event()
2121         strcpy(popup->asset->vcodec, FileMOV::strtocompression(get_text()));
2122         popup->update_parameters();
2123         return 1;