r851: Merge 2.1:
[cinelerra_cv.git] / cinelerra / filempeg.C
blobb1255f5d6aeaba9cb781cfb8d496a10f97dcae0f
1 #include "asset.h"
2 #include "bcprogressbox.h"
3 #include "bcsignals.h"
4 #include "bitspopup.h"
5 #include "byteorder.h"
6 #include "clip.h"
7 #include "condition.h"
8 #include "edit.h"
9 #include "file.h"
10 #include "filempeg.h"
11 #include "filesystem.h"
12 #include "guicast.h"
13 #include "indexfile.h"
14 #include "interlacemodes.h"
15 #include "language.h"
16 #include "mwindow.inc"
17 #include "preferences.h"
18 #include "vframe.h"
19 #include "videodevice.inc"
21 #include <stdio.h>
22 #include <string.h>
23 #include <unistd.h>
25 #define MPEG_YUV420 0
26 #define MPEG_YUV422 1
29 #define MJPEG_EXE PLUGIN_DIR "/mpeg2enc.plugin"
37 // M JPEG dependancies
38 static double frame_rate_codes[] = 
40         0,
41         24000.0/1001.0,
42         24.0,
43         25.0,
44         30000.0/1001.0,
45         30.0,
46         50.0,
47         60000.0/1001.0,
48         60.0
51 static double aspect_ratio_codes[] =
53         0,
54         1.0,
55         1.333,
56         1.777,
57         2.11
67 FileMPEG::FileMPEG(Asset *asset, File *file)
68  : FileBase(asset, file)
70         reset_parameters();
71 // May also be VMPEG or AMPEG if write status.
72         if(asset->format == FILE_UNKNOWN) asset->format = FILE_MPEG;
73         asset->byte_order = 0;
74         next_frame_lock = new Condition(0, "FileMPEG::next_frame_lock");
75         next_frame_done = new Condition(0, "FileMPEG::next_frame_done");
78 FileMPEG::~FileMPEG()
80         close_file();
81         delete next_frame_lock;
82         delete next_frame_done;
85 void FileMPEG::get_parameters(BC_WindowBase *parent_window, 
86         Asset *asset, 
87         BC_WindowBase* &format_window,
88         int audio_options,
89         int video_options)
91         if(audio_options && asset->format == FILE_AMPEG)
92         {
93                 MPEGConfigAudio *window = new MPEGConfigAudio(parent_window, asset);
94                 format_window = window;
95                 window->create_objects();
96                 window->run_window();
97                 delete window;
98         }
99         else
100         if(video_options && asset->format == FILE_VMPEG)
101         {
102                 MPEGConfigVideo *window = new MPEGConfigVideo(parent_window, asset);
103                 format_window = window;
104                 window->create_objects();
105                 window->run_window();
106                 delete window;
107         }
110 int FileMPEG::check_sig(Asset *asset)
112         return mpeg3_check_sig(asset->path);
115 int FileMPEG::reset_parameters_derived()
117         wrote_header = 0;
118         mjpeg_out = 0;
119         mjpeg_eof = 0;
120         mjpeg_error = 0;
124         fd = 0;
125         video_out = 0;
126         audio_out = 0;
127         prev_track = 0;
128         temp_frame = 0;
129         toolame_temp = 0;
130         toolame_allocation = 0;
131         toolame_result = 0;
132         lame_temp[0] = 0;
133         lame_temp[1] = 0;
134         lame_allocation = 0;
135         lame_global = 0;
136         lame_output = 0;
137         lame_output_allocation = 0;
138         lame_fd = 0;
139         lame_started = 0;
143 // Just create the Quicktime objects since this routine is also called
144 // for reopening.
145 int FileMPEG::open_file(int rd, int wr)
147 SET_TRACE
148         int result = 0;
149         this->rd = rd;
150         this->wr = wr;
152         if(rd)
153         {
154                 int error = 0;
155                 if(!(fd = mpeg3_open(asset->path, &error)))
156                 {
157                         printf("FileMPEG::open_file %s\n", asset->path);
158                         result = 1;
159                 }
160                 else
161                 {
162 // Determine if the file needs a table of contents and create one if needed.
163                         if(!mpeg3_has_toc(fd))
164                         {
165 // If it has video it must be scanned since video has keyframes.
166                                 if(mpeg3_total_vstreams(fd))
167                                 {
168                                         if(create_index()) return 1;
169                                 }
170                         }
172                         mpeg3_set_cpus(fd, file->cpus);
174                         asset->audio_data = mpeg3_has_audio(fd);
175                         if(asset->audio_data)
176                         {
177                                 asset->channels = 0;
178                                 for(int i = 0; i < mpeg3_total_astreams(fd); i++)
179                                 {
180                                         asset->channels += mpeg3_audio_channels(fd, i);
181                                 }
182                                 if(!asset->sample_rate)
183                                         asset->sample_rate = mpeg3_sample_rate(fd, 0);
184                                 asset->audio_length = mpeg3_audio_samples(fd, 0); 
185                         }
187                         asset->video_data = mpeg3_has_video(fd);
188                         if(asset->video_data)
189                         {
190                                 asset->layers = mpeg3_total_vstreams(fd);
191                                 asset->width = mpeg3_video_width(fd, 0);
192                                 asset->height = mpeg3_video_height(fd, 0);
193                                 asset->interlace_mode = BC_ILACE_MODE_UNDETECTED; // TODO: (to do this, start at hvirtualcvs/libmpeg3/headers.c 
194                                                                                   //        and find out how to decode info from the header)
195                                 asset->video_length = mpeg3_video_frames(fd, 0);
196                                 asset->vmpeg_cmodel = 
197                                         (mpeg3_colormodel(fd, 0) == MPEG3_YUV422P) ? MPEG_YUV422 : MPEG_YUV420;
198                                 if(!asset->frame_rate)
199                                         asset->frame_rate = mpeg3_frame_rate(fd, 0);
200                         }
201                 }
202         }
203         
204         
205         
206         if(wr && asset->format == FILE_VMPEG)
207         {
208 // Heroine Virtual encoder
209                 if(asset->vmpeg_cmodel == MPEG_YUV422)
210                 {
211                         char bitrate_string[BCTEXTLEN];
212                         char quant_string[BCTEXTLEN];
213                         char iframe_string[BCTEXTLEN];
215                         sprintf(bitrate_string, "%d", asset->vmpeg_bitrate);
216                         sprintf(quant_string, "%d", asset->vmpeg_quantization);
217                         sprintf(iframe_string, "%d", asset->vmpeg_iframe_distance);
219 // Construct command line
220                         if(!result)
221                         {
222                                 append_vcommand_line("mpeg2enc");
225                                 if(asset->aspect_ratio > 0)
226                                 {
227                                         append_vcommand_line("-a");
228                                         if(EQUIV(asset->aspect_ratio, 1))
229                                                 append_vcommand_line("1");
230                                         else
231                                         if(EQUIV(asset->aspect_ratio, 1.333))
232                                                 append_vcommand_line("2");
233                                         else
234                                         if(EQUIV(asset->aspect_ratio, 1.777))
235                                                 append_vcommand_line("3");
236                                         else
237                                         if(EQUIV(asset->aspect_ratio, 2.11))
238                                                 append_vcommand_line("4");
239                                 }
241                                 append_vcommand_line(asset->vmpeg_derivative == 1 ? "-1" : "");
242                                 append_vcommand_line(asset->vmpeg_cmodel == MPEG_YUV422 ? "-422" : "");
243                                 if(asset->vmpeg_fix_bitrate)
244                                 {
245                                         append_vcommand_line("--cbr -b");
246                                         append_vcommand_line(bitrate_string);
247                                 }
248                                 else
249                                 {
250                                         append_vcommand_line("-q");
251                                         append_vcommand_line(quant_string);
252                                 }
253                                 append_vcommand_line(!asset->vmpeg_fix_bitrate ? quant_string : "");
254                                 append_vcommand_line("-n");
255                                 append_vcommand_line(iframe_string);
256                                 append_vcommand_line(asset->vmpeg_progressive ? "-p" : "");
257                                 append_vcommand_line(asset->vmpeg_denoise ? "-d" : "");
258                                 append_vcommand_line(file->cpus <= 1 ? "-u" : "");
259                                 append_vcommand_line(asset->vmpeg_seq_codes ? "-g" : "");
260                                 append_vcommand_line(asset->path);
262                                 video_out = new FileMPEGVideo(this);
263                                 video_out->start();
264                         }
265                 }
266                 else
267 // mjpegtools encoder
268                 {
269                         char string[BCTEXTLEN];
270                         sprintf(mjpeg_command, MJPEG_EXE);
272                         if(asset->vmpeg_fix_bitrate)
273                         {
274                                 sprintf(string, " --cbr -b %d", asset->vmpeg_bitrate);
275                         }
276                         else
277                         {
278                                 sprintf(string, " -q %d", asset->vmpeg_quantization);
279                         }
280                         strcat(mjpeg_command, string);
287 // Aspect ratio
288                         int aspect_ratio_code = -1;
289                         if(asset->aspect_ratio > 0)
290                         {
291                                 for(int i = 0; i < sizeof(aspect_ratio_codes) / sizeof(double); i++)
292                                 {
293                                         if(EQUIV(aspect_ratio_codes[i], asset->aspect_ratio))
294                                         {
295                                                 aspect_ratio_code = i;
296                                                 break;
297                                         }
298                                 }
299                         }
300                         if(aspect_ratio_code < 0)
301                         {
302                                 printf("FileMPEG::open_file: Unsupported aspect ratio %f\n", asset->aspect_ratio);
303                                 aspect_ratio_code = 2;
304                         }
305                         sprintf(string, " -a %d", aspect_ratio_code);
306                         strcat(mjpeg_command, string);
313 // Frame rate
314                         int frame_rate_code = -1;
315                 for(int i = 1; sizeof(frame_rate_codes) / sizeof(double); ++i)
316                         {
317                                 if(EQUIV(asset->frame_rate, frame_rate_codes[i]))
318                                 {
319                                         frame_rate_code = i;
320                                         break;
321                                 }
322                         }
323                         if(frame_rate_code < 0)
324                         {
325                                 frame_rate_code = 4;
326                                 printf("FileMPEG::open_file: Unsupported frame rate %f\n", asset->frame_rate);
327                         }
328                         sprintf(string, " -F %d", frame_rate_code);
329                         strcat(mjpeg_command, string);
335                         strcat(mjpeg_command, 
336                                 asset->vmpeg_progressive ? " -I 0" : " -I 1");
337                         
340                         sprintf(string, " -M %d", file->cpus);
341                         strcat(mjpeg_command, string);
344                         if(!asset->vmpeg_progressive)
345                         {
346                                 strcat(mjpeg_command, asset->vmpeg_field_order ? " -z b" : " -z t");
347                         }
350                         sprintf(string, " -f %d", asset->vmpeg_preset);
351                         strcat(mjpeg_command, string);
354                         sprintf(string, " -g %d -G %d", asset->vmpeg_iframe_distance, asset->vmpeg_iframe_distance);
355                         strcat(mjpeg_command, string);
358                         if(asset->vmpeg_seq_codes) strcat(mjpeg_command, " -s");
361                         sprintf(string, " -R %d", CLAMP(asset->vmpeg_pframe_distance, 0, 2));
362                         strcat(mjpeg_command, string);
364                         sprintf(string, " -o '%s'", asset->path);
365                         strcat(mjpeg_command, string);
369                         printf("FileMPEG::open_file: Running %s\n", mjpeg_command);
370                         if(!(mjpeg_out = popen(mjpeg_command, "w")))
371                         {
372                                 perror("FileMPEG::open_file");
373                         }
375                         video_out = new FileMPEGVideo(this);
376                         video_out->start();
377                 }
378         }
380         if(wr && asset->format == FILE_AMPEG)
381         {
382                 char command_line[BCTEXTLEN];
383                 char encoder_string[BCTEXTLEN];
384                 char argument_string[BCTEXTLEN];
386 //printf("FileMPEG::open_file 1 %d\n", asset->ampeg_derivative);
387                 encoder_string[0] = 0;
389                 if(asset->ampeg_derivative == 2)
390                 {
391                         char string[BCTEXTLEN];
392                         append_acommand_line("toolame");
393                         append_acommand_line("-m");
394                         append_acommand_line((asset->channels >= 2) ? "j" : "m");
395                         sprintf(string, "%f", (float)asset->sample_rate / 1000);
396                         append_acommand_line("-s");
397                         append_acommand_line(string);
398                         sprintf(string, "%d", asset->ampeg_bitrate);
399                         append_acommand_line("-b");
400                         append_acommand_line(string);
401                         append_acommand_line("-");
402                         append_acommand_line(asset->path);
404                         audio_out = new FileMPEGAudio(this);
405                         audio_out->start();
406                 }
407                 else
408                 if(asset->ampeg_derivative == 3)
409                 {
410                         lame_global = lame_init();
411                         lame_set_brate(lame_global, asset->ampeg_bitrate / 1000);
412                         lame_set_quality(lame_global, 0);
413                         lame_set_in_samplerate(lame_global, 
414                                 asset->sample_rate);
415                         if((result = lame_init_params(lame_global)) < 0)
416                         {
417                                 printf(_("encode: lame_init_params returned %d\n"), result);
418                                 lame_close(lame_global);
419                                 lame_global = 0;
420                         }
421                         else
422                         if(!(lame_fd = fopen(asset->path, "w")))
423                         {
424                                 perror("FileMPEG::open_file");
425                                 lame_close(lame_global);
426                                 lame_global = 0;
427                         }
428                 }
429                 else
430                 {
431                         printf("FileMPEG::open_file: ampeg_derivative=%d\n", asset->ampeg_derivative);
432                         result = 1;
433                 }
434         }
436 //asset->dump();
437 SET_TRACE
438         return result;
448 int FileMPEG::create_index()
450 // Calculate TOC path
451         char index_filename[BCTEXTLEN];
452         char source_filename[BCTEXTLEN];
453         IndexFile::get_index_filename(source_filename, 
454                 file->preferences->index_directory, 
455                 index_filename, 
456                 asset->path);
457         char *ptr = strrchr(index_filename, '.');
458         int error = 0;
460         if(!ptr) return 1;
462         sprintf(ptr, ".toc");
464 // Test existence of TOC
465         FILE *test = fopen(index_filename, "r");
466         if(test)
467         {
468 // Reopen with table of contents
469                 fclose(test);
470         }
471         else
472         {
473 // Create progress window.
474 // This gets around the fact that MWindowGUI is locked.
475                 char progress_title[BCTEXTLEN];
476                 char string[BCTEXTLEN];
477                 sprintf(progress_title, "Creating %s\n", index_filename);
478                 int64_t total_bytes;
479                 mpeg3_t *index_file = mpeg3_start_toc(asset->path, index_filename, &total_bytes);
480                 struct timeval new_time;
481                 struct timeval prev_time;
482                 struct timeval start_time;
483                 struct timeval current_time;
484                 gettimeofday(&prev_time, 0);
485                 gettimeofday(&start_time, 0);
487                 BC_ProgressBox *progress = new BC_ProgressBox(-1, 
488                         -1, 
489                         progress_title, 
490                         total_bytes);
491                 progress->start();
492                 int result = 0;
493                 while(1)
494                 {
495                         int64_t bytes_processed;
496                         mpeg3_do_toc(index_file, &bytes_processed);
497                         gettimeofday(&new_time, 0);
499                         if(new_time.tv_sec - prev_time.tv_sec >= 1)
500                         {
501                                 gettimeofday(&current_time, 0);
502                                 int64_t elapsed_seconds = current_time.tv_sec - start_time.tv_sec;
503                                 int64_t total_seconds = elapsed_seconds * total_bytes / bytes_processed;
504                                 int64_t eta = total_seconds - elapsed_seconds;
505                                 progress->update(bytes_processed, 1);
506                                 sprintf(string, 
507                                         "%sETA: %lldm%llds",
508                                         progress_title,
509                                         eta / 60,
510                                         eta % 60);
511                                 progress->update_title(string, 1);
512 //                              fprintf(stderr, "ETA: %dm%ds        \r", 
513 //                                      bytes_processed * 100 / total_bytes,
514 //                                      eta / 60,
515 //                                      eta % 60);
516 //                              fflush(stdout);
517                                 prev_time = new_time;
518                         }
519                         if(bytes_processed >= total_bytes) break;
520                         if(progress->is_cancelled()) 
521                         {
522                                 result = 1;
523                                 break;
524                         }
525                 }
527                 mpeg3_stop_toc(index_file);
529                 progress->stop_progress();
530                 delete progress;
532 // Remove if error
533                 if(result)
534                 {
535                         remove(index_filename);
536                         return 1;
537                 }
538                 else
539 // Fix date to date of source if success
540                 {
541                 }
543         }
547 // Reopen file from index path instead of asset path.
548         if(fd) mpeg3_close(fd);
549         if(!(fd = mpeg3_open(index_filename, &error)))
550         {
551                 return 1;
552         }
553         else
554                 return 0;
562 void FileMPEG::append_vcommand_line(const char *string)
564         if(string[0])
565         {
566                 char *argv = strdup(string);
567                 vcommand_line.append(argv);
568         }
571 void FileMPEG::append_acommand_line(const char *string)
573         if(string[0])
574         {
575                 char *argv = strdup(string);
576                 acommand_line.append(argv);
577         }
581 int FileMPEG::close_file()
583         mjpeg_eof = 1;
584         next_frame_lock->unlock();
586         if(fd)
587         {
588                 mpeg3_close(fd);
589         }
591         if(video_out)
592         {
593 // End of sequence signal
594                 if(file->asset->vmpeg_cmodel == MPEG_YUV422)
595                 {
596                         mpeg2enc_set_input_buffers(1, 0, 0, 0);
597                 }
598                 delete video_out;
599                 video_out = 0;
600         }
602         vcommand_line.remove_all_objects();
603         acommand_line.remove_all_objects();
605         if(audio_out)
606         {
607                 toolame_send_buffer(0, 0);
608                 delete audio_out;
609                 audio_out = 0;
610         }
612         if(lame_global)
613                 lame_close(lame_global);
615         if(temp_frame) delete temp_frame;
616         if(toolame_temp) delete [] toolame_temp;
618         if(lame_temp[0]) delete [] lame_temp[0];
619         if(lame_temp[1]) delete [] lame_temp[1];
620         if(lame_output) delete [] lame_output;
621         if(lame_fd) fclose(lame_fd);
623         if(mjpeg_out) fclose(mjpeg_out);
624         reset_parameters();
626         FileBase::close_file();
627         return 0;
630 int FileMPEG::get_best_colormodel(Asset *asset, int driver)
632 //printf("FileMPEG::get_best_colormodel 1\n");
633         switch(driver)
634         {
635                 case PLAYBACK_X11:
636                         return BC_RGB888;
637                         if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
638                         if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
639                         break;
640                 case PLAYBACK_X11_XV:
641                         if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
642                         if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
643                         break;
644                 case PLAYBACK_LML:
645                 case PLAYBACK_BUZ:
646                         return BC_YUV422P;
647                         break;
648                 case PLAYBACK_DV1394:
649                 case PLAYBACK_FIREWIRE:
650                         return BC_YUV422P;
651                         break;
652                 case VIDEO4LINUX:
653                 case VIDEO4LINUX2:
654                         if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
655                         if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
656                         break;
657                 case CAPTURE_BUZ:
658                 case CAPTURE_LML:
659                         return BC_YUV422;
660                         break;
661                 case CAPTURE_FIREWIRE:
662                 case CAPTURE_IEC61883:
663                         return BC_YUV422P;
664                         break;
665         }
666 //printf("FileMPEG::get_best_colormodel 100\n");
669 int FileMPEG::colormodel_supported(int colormodel)
671         return colormodel;
674 int FileMPEG::get_index(char *index_path)
676         if(!fd) return 1;
679 // Convert the index tables from tracks to channels.
680         if(mpeg3_index_tracks(fd))
681         {
682 // Calculate size of buffer needed for all channels
683                 int buffer_size = 0;
684                 for(int i = 0; i < mpeg3_index_tracks(fd); i++)
685                 {
686                         buffer_size += mpeg3_index_size(fd, i) *
687                                 mpeg3_index_channels(fd, i) *
688                                 2;
689                 }
691                 asset->index_buffer = new float[buffer_size];
693 // Size of index buffer in floats
694                 int current_offset = 0;
695 // Current asset channel
696                 int current_channel = 0;
697                 asset->index_zoom = mpeg3_index_zoom(fd);
698                 asset->index_offsets = new int64_t[asset->channels];
699                 asset->index_sizes = new int64_t[asset->channels];
700                 for(int i = 0; i < mpeg3_index_tracks(fd); i++)
701                 {
702                         for(int j = 0; j < mpeg3_index_channels(fd, i); j++)
703                         {
704                                 asset->index_offsets[current_channel] = current_offset;
705                                 asset->index_sizes[current_channel] = mpeg3_index_size(fd, i) * 2;
706                                 memcpy(asset->index_buffer + current_offset,
707                                         mpeg3_index_data(fd, i, j),
708                                         mpeg3_index_size(fd, i) * sizeof(float) * 2);
710                                 current_offset += mpeg3_index_size(fd, i) * 2;
711                                 current_channel++;
712                         }
713                 }
715                 FileSystem fs;
716                 asset->index_bytes = fs.get_size(asset->path);
718                 asset->write_index(index_path, buffer_size * sizeof(float));
719                 delete [] asset->index_buffer;
721                 return 0;
722         }
724         return 1;
728 int FileMPEG::can_copy_from(Edit *edit, int64_t position)
730         if(!fd) return 0;
731         return 0;
734 int FileMPEG::set_audio_position(int64_t sample)
736 #if 0
737         if(!fd) return 1;
738         
739         int channel, stream;
740         to_streamchannel(file->current_channel, stream, channel);
742 //printf("FileMPEG::set_audio_position %d %d %d\n", sample, mpeg3_get_sample(fd, stream), last_sample);
743         if(sample != mpeg3_get_sample(fd, stream) &&
744                 sample != last_sample)
745         {
746                 if(sample >= 0 && sample < asset->audio_length)
747                 {
748 //printf("FileMPEG::set_audio_position seeking stream %d\n", sample);
749                         return mpeg3_set_sample(fd, sample, stream);
750                 }
751                 else
752                         return 1;
753         }
754 #endif
755         return 0;
758 int FileMPEG::set_video_position(int64_t x)
760         if(!fd) return 1;
761         if(x >= 0 && x < asset->video_length)
762         {
763 //printf("FileMPEG::set_video_position 1 %lld\n", x);
764                 mpeg3_set_frame(fd, x, file->current_layer);
765         }
766         else
767                 return 1;
770 int64_t FileMPEG::get_memory_usage()
772         if(rd && fd)
773         {
774                 int64_t result = mpeg3_memory_usage(fd);
775                 return result;
776         }
777         return 0;
781 int FileMPEG::write_samples(double **buffer, int64_t len)
783         int result = 0;
785 //printf("FileMPEG::write_samples 1\n");
786         if(asset->ampeg_derivative == 2)
787         {
788 // Convert to int16
789                 int channels = MIN(asset->channels, 2);
790                 int64_t audio_size = len * channels * 2;
791                 if(toolame_allocation < audio_size)
792                 {
793                         if(toolame_temp) delete [] toolame_temp;
794                         toolame_temp = new unsigned char[audio_size];
795                         toolame_allocation = audio_size;
796                 }
798                 for(int i = 0; i < channels; i++)
799                 {
800                         int16_t *output = ((int16_t*)toolame_temp) + i;
801                         double *input = buffer[i];
802                         for(int j = 0; j < len; j++)
803                         {
804                                 int sample = (int)(*input * 0x7fff);
805                                 *output = (int16_t)(CLIP(sample, -0x8000, 0x7fff));
806                                 output += channels;
807                                 input++;
808                         }
809                 }
810                 result = toolame_send_buffer((char*)toolame_temp, audio_size);
811         }
812         else
813         if(asset->ampeg_derivative == 3)
814         {
815                 int channels = MIN(asset->channels, 2);
816                 int64_t audio_size = len * channels;
817                 if(!lame_global) return 1;
818                 if(!lame_fd) return 1;
819                 if(lame_allocation < audio_size)
820                 {
821                         if(lame_temp[0]) delete [] lame_temp[0];
822                         if(lame_temp[1]) delete [] lame_temp[1];
823                         lame_temp[0] = new float[audio_size];
824                         lame_temp[1] = new float[audio_size];
825                         lame_allocation = audio_size;
826                 }
828                 if(lame_output_allocation < audio_size * 4)
829                 {
830                         if(lame_output) delete [] lame_output;
831                         lame_output_allocation = audio_size * 4;
832                         lame_output = new char[lame_output_allocation];
833                 }
835                 for(int i = 0; i < channels; i++)
836                 {
837                         float *output = lame_temp[i];
838                         double *input = buffer[i];
839                         for(int j = 0; j < len; j++)
840                         {
841                                 *output++ = *input++ * (float)32768;
842                         }
843                 }
845                 result = lame_encode_buffer_float(lame_global,
846                         lame_temp[0],
847                         (channels > 1) ? lame_temp[1] : lame_temp[0],
848                         len,
849                         (unsigned char*)lame_output,
850                         lame_output_allocation);
851                 if(result > 0)
852                 {
853                         char *real_output = lame_output;
854                         int bytes = result;
855                         if(!lame_started)
856                         {
857                                 for(int i = 0; i < bytes; i++)
858                                         if(lame_output[i])
859                                         {
860                                                 real_output = &lame_output[i];
861                                                 lame_started = 1;
862                                                 bytes -= i;
863                                                 break;
864                                         }
865                         }
866                         if(bytes > 0 && lame_started)
867                         {
868                                 result = !fwrite(real_output, 1, bytes, lame_fd);
869                                 if(result)
870                                         perror("FileMPEG::write_samples");
871                         }
872                         else
873                                 result = 0;
874                 }
875                 else
876                         result = 1;
877         }
879         return result;
882 int FileMPEG::write_frames(VFrame ***frames, int len)
884         int result = 0;
886         if(video_out)
887         {
888                 int temp_w = (int)((asset->width + 15) / 16) * 16;
889                 int temp_h;
892                 int output_cmodel = 
893                         (asset->vmpeg_cmodel == MPEG_YUV420) ? BC_YUV420P : BC_YUV422P;
894                 
895                 
896 // Height depends on progressiveness
897                 if(asset->vmpeg_progressive || asset->vmpeg_derivative == 1)
898                         temp_h = (int)((asset->height + 15) / 16) * 16;
899                 else
900                         temp_h = (int)((asset->height + 31) / 32) * 32;
902 //printf("FileMPEG::write_frames 1\n");
903                 
904 // Only 1 layer is supported in MPEG output
905                 for(int i = 0; i < 1; i++)
906                 {
907                         for(int j = 0; j < len && !result; j++)
908                         {
909                                 VFrame *frame = frames[i][j];
910                                 
911                                 
912                                 
913                                 if(asset->vmpeg_cmodel == MPEG_YUV422)
914                                 {
915                                         if(frame->get_w() == temp_w &&
916                                                 frame->get_h() == temp_h &&
917                                                 frame->get_color_model() == output_cmodel)
918                                         {
919                                                 mpeg2enc_set_input_buffers(0, 
920                                                         (char*)frame->get_y(),
921                                                         (char*)frame->get_u(),
922                                                         (char*)frame->get_v());
923                                         }
924                                         else
925                                         {
926                                                 if(temp_frame &&
927                                                         (temp_frame->get_w() != temp_w ||
928                                                         temp_frame->get_h() != temp_h ||
929                                                         temp_frame->get_color_model() || output_cmodel))
930                                                 {
931                                                         delete temp_frame;
932                                                         temp_frame = 0;
933                                                 }
936                                                 if(!temp_frame)
937                                                 {
938                                                         temp_frame = new VFrame(0, 
939                                                                 temp_w, 
940                                                                 temp_h, 
941                                                                 output_cmodel);
942                                                 }
944                                                 cmodel_transfer(temp_frame->get_rows(), 
945                                                         frame->get_rows(),
946                                                         temp_frame->get_y(),
947                                                         temp_frame->get_u(),
948                                                         temp_frame->get_v(),
949                                                         frame->get_y(),
950                                                         frame->get_u(),
951                                                         frame->get_v(),
952                                                         0,
953                                                         0,
954                                                         asset->width,
955                                                         asset->height,
956                                                         0,
957                                                         0,
958                                                         asset->width,
959                                                         asset->height,
960                                                         frame->get_color_model(), 
961                                                         temp_frame->get_color_model(),
962                                                         0, 
963                                                         frame->get_w(),
964                                                         temp_w);
966                                                 mpeg2enc_set_input_buffers(0, 
967                                                         (char*)temp_frame->get_y(),
968                                                         (char*)temp_frame->get_u(),
969                                                         (char*)temp_frame->get_v());
970                                         }
971                                 }
972                                 else
973                                 {
974 // MJPEG uses the same dimensions as the input
975                                         if(frame->get_color_model() == output_cmodel)
976                                         {
977                                                 mjpeg_y = frame->get_y();
978                                                 mjpeg_u = frame->get_u();
979                                                 mjpeg_v = frame->get_v();
980                                         }
981                                         else
982                                         {
983                                                 if(!temp_frame)
984                                                 {
985                                                         temp_frame = new VFrame(0, 
986                                                                 asset->width, 
987                                                                 asset->height, 
988                                                                 output_cmodel);
989                                                 }
991                                                 cmodel_transfer(temp_frame->get_rows(), 
992                                                         frame->get_rows(),
993                                                         temp_frame->get_y(),
994                                                         temp_frame->get_u(),
995                                                         temp_frame->get_v(),
996                                                         frame->get_y(),
997                                                         frame->get_u(),
998                                                         frame->get_v(),
999                                                         0,
1000                                                         0,
1001                                                         asset->width,
1002                                                         asset->height,
1003                                                         0,
1004                                                         0,
1005                                                         asset->width,
1006                                                         asset->height,
1007                                                         frame->get_color_model(), 
1008                                                         temp_frame->get_color_model(),
1009                                                         0, 
1010                                                         frame->get_w(),
1011                                                         temp_w);
1013                                                 mjpeg_y = temp_frame->get_y();
1014                                                 mjpeg_u = temp_frame->get_u();
1015                                                 mjpeg_v = temp_frame->get_v();
1016                                         }
1021                                         next_frame_lock->unlock();
1022                                         next_frame_done->lock("FileMPEG::write_frames");
1023                                         if(mjpeg_error) result = 1;
1024                                 }
1030                         }
1031                 }
1032         }
1036         return result;
1039 int FileMPEG::read_frame(VFrame *frame)
1041         if(!fd) return 1;
1042         int result = 0;
1043         int src_cmodel;
1045 // printf("FileMPEG::read_frame\n");
1046 // frame->dump_stacks();
1047 // frame->dump_params();
1049         if(mpeg3_colormodel(fd, 0) == MPEG3_YUV420P)
1050                 src_cmodel = BC_YUV420P;
1051         else
1052         if(mpeg3_colormodel(fd, 0) == MPEG3_YUV422P)
1053                 src_cmodel = BC_YUV422P;
1055         switch(frame->get_color_model())
1056         {
1057                 case MPEG3_RGB565:
1058                 case MPEG3_BGR888:
1059                 case MPEG3_BGRA8888:
1060                 case MPEG3_RGB888:
1061                 case MPEG3_RGBA8888:
1062                 case MPEG3_RGBA16161616:
1063 SET_TRACE
1064                         mpeg3_read_frame(fd, 
1065                                         frame->get_rows(), /* Array of pointers to the start of each output row */
1066                                         0,                    /* Location in input frame to take picture */
1067                                         0, 
1068                                         asset->width, 
1069                                         asset->height, 
1070                                         asset->width,                   /* Dimensions of output_rows */
1071                                         asset->height, 
1072                                         frame->get_color_model(),             /* One of the color model #defines */
1073                                         file->current_layer);
1074 SET_TRACE
1075                         break;
1077 // Use Temp
1078                 default:
1079 // Read these directly
1080                         if(frame->get_color_model() == src_cmodel)
1081                         {
1082 SET_TRACE
1083                                 mpeg3_read_yuvframe(fd,
1084                                         (char*)frame->get_y(),
1085                                         (char*)frame->get_u(),
1086                                         (char*)frame->get_v(),
1087                                         0,
1088                                         0,
1089                                         asset->width,
1090                                         asset->height,
1091                                         file->current_layer);
1092 SET_TRACE
1093                         }
1094                         else
1095 // Process through temp frame
1096                         {
1097                                 char *y, *u, *v;
1098 SET_TRACE
1099                                 mpeg3_read_yuvframe_ptr(fd,
1100                                         &y,
1101                                         &u,
1102                                         &v,
1103                                         file->current_layer);
1104 SET_TRACE
1105                                 if(y && u && v)
1106                                 {
1107                                         cmodel_transfer(frame->get_rows(), 
1108                                                 0,
1109                                                 frame->get_y(),
1110                                                 frame->get_u(),
1111                                                 frame->get_v(),
1112                                                 (unsigned char*)y,
1113                                                 (unsigned char*)u,
1114                                                 (unsigned char*)v,
1115                                                 0,
1116                                                 0,
1117                                                 asset->width,
1118                                                 asset->height,
1119                                                 0,
1120                                                 0,
1121                                                 asset->width,
1122                                                 asset->height,
1123                                                 src_cmodel, 
1124                                                 frame->get_color_model(),
1125                                                 0, 
1126                                                 asset->width,
1127                                                 frame->get_w());
1128                                 }
1129                         }
1130                         break;
1131         }
1133 SET_TRACE
1134         return result;
1138 void FileMPEG::to_streamchannel(int channel, int &stream_out, int &channel_out)
1140         for(stream_out = 0, channel_out = file->current_channel; 
1141                 stream_out < mpeg3_total_astreams(fd) && 
1142                         channel_out >= mpeg3_audio_channels(fd, stream_out);
1143                 channel_out -= mpeg3_audio_channels(fd, stream_out), stream_out++)
1144         ;
1147 int FileMPEG::read_samples(double *buffer, int64_t len)
1149         if(!fd) return 0;
1150         if(len < 0) return 0;
1152 // This is directed to a FileMPEGBuffer
1153         float *temp_float = new float[len];
1154 // Translate pure channel to a stream and a channel in the mpeg stream
1155         int stream, channel;
1156         to_streamchannel(file->current_channel, stream, channel);
1157         
1158         
1159         
1160 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
1162         mpeg3_set_sample(fd, 
1163                 file->current_sample,
1164                 stream);
1165         mpeg3_read_audio(fd, 
1166                 temp_float,      /* Pointer to pre-allocated buffer of floats */
1167                 0,      /* Pointer to pre-allocated buffer of int16's */
1168                 channel,          /* Channel to decode */
1169                 len,         /* Number of samples to decode */
1170                 stream);          /* Stream containing the channel */
1173 //      last_sample = file->current_sample;
1174         for(int i = 0; i < len; i++) buffer[i] = temp_float[i];
1176         delete [] temp_float;
1177         return 0;
1180 int FileMPEG::prefer_samples_float()
1182         return 1;
1185 int FileMPEG::read_samples_float(float *buffer, int64_t len)
1187         if(!fd) return 0;
1189 // Translate pure channel to a stream and a channel in the mpeg stream
1190         int stream, channel;
1191         to_streamchannel(file->current_channel, stream, channel);
1192         
1193         
1194 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
1196         mpeg3_set_sample(fd, 
1197                 file->current_sample,
1198                 stream);
1199         mpeg3_read_audio(fd, 
1200                 buffer,         /* Pointer to pre-allocated buffer of floats */
1201                 0,              /* Pointer to pre-allocated buffer of int16's */
1202                 channel,          /* Channel to decode */
1203                 len,         /* Number of samples to decode */
1204                 stream);          /* Stream containing the channel */
1207 //      last_sample = file->current_sample;
1209 //printf("FileMPEG::read_samples 100\n");
1210         return 0;
1215 char* FileMPEG::strtocompression(char *string)
1217         return "";
1220 char* FileMPEG::compressiontostr(char *string)
1222         return "";
1231 FileMPEGVideo::FileMPEGVideo(FileMPEG *file)
1232  : Thread(1, 0, 0)
1234         this->file = file;
1235         
1236         
1237         if(file->asset->vmpeg_cmodel == MPEG_YUV422)
1238         {
1239                 mpeg2enc_init_buffers();
1240                 mpeg2enc_set_w(file->asset->width);
1241                 mpeg2enc_set_h(file->asset->height);
1242                 mpeg2enc_set_rate(file->asset->frame_rate);
1243         }
1246 FileMPEGVideo::~FileMPEGVideo()
1248         Thread::join();
1251 void FileMPEGVideo::run()
1253         if(file->asset->vmpeg_cmodel == MPEG_YUV422)
1254         {
1255                 printf("FileMPEGVideo::run ");
1256                 for(int i = 0; i < file->vcommand_line.total; i++)
1257                 printf("%s ", file->vcommand_line.values[i]);
1258                 printf("\n");
1259                 mpeg2enc(file->vcommand_line.total, file->vcommand_line.values);
1260         }
1261         else
1262         {
1263                 while(1)
1264                 {
1265                         file->next_frame_lock->lock("FileMPEGVideo::run");
1266                         if(file->mjpeg_eof) 
1267                         {
1268                                 file->next_frame_done->unlock();
1269                                 break;
1270                         }
1274 // YUV4 sequence header
1275                         if(!file->wrote_header)
1276                         {
1277                                 file->wrote_header = 1;
1279                                 char string[BCTEXTLEN];
1280                                 char interlace_string[BCTEXTLEN];
1281                                 if(!file->asset->vmpeg_progressive)
1282                                 {
1283                                         sprintf(interlace_string, file->asset->vmpeg_field_order ? "b" : "t");
1284                                 }
1285                                 else
1286                                 {
1287                                         sprintf(interlace_string, "p");
1288                                 }
1290                                 fprintf(file->mjpeg_out, "YUV4MPEG2 W%d H%d F%d:%d I%s A%d:%d C%s\n",
1291                                         file->asset->width,
1292                                         file->asset->height,
1293                                         (int)(file->asset->frame_rate * 1001),
1294                                         1001,
1295                                         interlace_string,
1296                                         (int)(file->asset->aspect_ratio * 1000),
1297                                         1000,
1298                                         "420mpeg2");
1299                         }
1301 // YUV4 frame header
1302                         fprintf(file->mjpeg_out, "FRAME\n");
1304 // YUV data
1305                         if(!fwrite(file->mjpeg_y, file->asset->width * file->asset->height, 1, file->mjpeg_out))
1306                                 file->mjpeg_error = 1;
1307                         if(!fwrite(file->mjpeg_u, file->asset->width * file->asset->height / 4, 1, file->mjpeg_out))
1308                                 file->mjpeg_error = 1;
1309                         if(!fwrite(file->mjpeg_v, file->asset->width * file->asset->height / 4, 1, file->mjpeg_out))
1310                                 file->mjpeg_error = 1;
1311                         fflush(file->mjpeg_out);
1313                         file->next_frame_done->unlock();
1314                 }
1315                 pclose(file->mjpeg_out);
1316                 file->mjpeg_out = 0;
1317         }
1339 FileMPEGAudio::FileMPEGAudio(FileMPEG *file)
1340  : Thread(1, 0, 0)
1342         this->file = file;
1343         toolame_init_buffers();
1346 FileMPEGAudio::~FileMPEGAudio()
1348         Thread::join();
1351 void FileMPEGAudio::run()
1353         file->toolame_result = toolame(file->acommand_line.total, file->acommand_line.values);
1363 MPEGConfigAudio::MPEGConfigAudio(BC_WindowBase *parent_window, Asset *asset)
1364  : BC_Window(PROGRAM_NAME ": Audio Compression",
1365         parent_window->get_abs_cursor_x(1),
1366         parent_window->get_abs_cursor_y(1),
1367         310,
1368         120,
1369         -1,
1370         -1,
1371         0,
1372         0,
1373         1)
1375         this->parent_window = parent_window;
1376         this->asset = asset;
1379 MPEGConfigAudio::~MPEGConfigAudio()
1383 int MPEGConfigAudio::create_objects()
1385         int x = 10, y = 10;
1386         int x1 = 150;
1387         MPEGLayer *layer;
1389         add_tool(new BC_Title(x, y, _("Layer:")));
1390         add_tool(layer = new MPEGLayer(x1, y, this));
1391         layer->create_objects();
1393         y += 30;
1394         add_tool(new BC_Title(x, y, _("Kbits per second:")));
1395         add_tool(bitrate = new MPEGABitrate(x1, y, this));
1396         bitrate->create_objects();
1397         
1398         
1399         add_subwindow(new BC_OKButton(this));
1400         show_window();
1401         flush();
1402         return 0;
1405 int MPEGConfigAudio::close_event()
1407         set_done(0);
1408         return 1;
1417 MPEGLayer::MPEGLayer(int x, int y, MPEGConfigAudio *gui)
1418  : BC_PopupMenu(x, y, 100, layer_to_string(gui->asset->ampeg_derivative))
1420         this->gui = gui;
1423 void MPEGLayer::create_objects()
1425         add_item(new BC_MenuItem(layer_to_string(2)));
1426         add_item(new BC_MenuItem(layer_to_string(3)));
1429 int MPEGLayer::handle_event()
1431         gui->asset->ampeg_derivative = string_to_layer(get_text());
1432         gui->bitrate->set_layer(gui->asset->ampeg_derivative);
1433         return 1;
1436 int MPEGLayer::string_to_layer(char *string)
1438         if(!strcasecmp(layer_to_string(2), string))
1439                 return 2;
1440         if(!strcasecmp(layer_to_string(3), string))
1441                 return 3;
1443         return 2;
1446 char* MPEGLayer::layer_to_string(int layer)
1448         switch(layer)
1449         {
1450                 case 2:
1451                         return _("II");
1452                         break;
1453                 
1454                 case 3:
1455                         return _("III");
1456                         break;
1457                         
1458                 default:
1459                         return _("II");
1460                         break;
1461         }
1470 MPEGABitrate::MPEGABitrate(int x, int y, MPEGConfigAudio *gui)
1471  : BC_PopupMenu(x, 
1472         y, 
1473         100, 
1474         bitrate_to_string(gui->string, gui->asset->ampeg_bitrate))
1476         this->gui = gui;
1479 void MPEGABitrate::create_objects()
1481         set_layer(gui->asset->ampeg_derivative);
1484 void MPEGABitrate::set_layer(int layer)
1486         while(total_items())
1487         {
1488                 remove_item(0);
1489         }
1491         if(layer == 2)
1492         {
1493                 add_item(new BC_MenuItem("160"));
1494                 add_item(new BC_MenuItem("192"));
1495                 add_item(new BC_MenuItem("224"));
1496                 add_item(new BC_MenuItem("256"));
1497                 add_item(new BC_MenuItem("320"));
1498                 add_item(new BC_MenuItem("384"));
1499         }
1500         else
1501         {
1502                 add_item(new BC_MenuItem("8"));
1503                 add_item(new BC_MenuItem("16"));
1504                 add_item(new BC_MenuItem("24"));
1505                 add_item(new BC_MenuItem("32"));
1506                 add_item(new BC_MenuItem("40"));
1507                 add_item(new BC_MenuItem("48"));
1508                 add_item(new BC_MenuItem("56"));
1509                 add_item(new BC_MenuItem("64"));
1510                 add_item(new BC_MenuItem("80"));
1511                 add_item(new BC_MenuItem("96"));
1512                 add_item(new BC_MenuItem("112"));
1513                 add_item(new BC_MenuItem("128"));
1514                 add_item(new BC_MenuItem("144"));
1515                 add_item(new BC_MenuItem("160"));
1516                 add_item(new BC_MenuItem("192"));
1517                 add_item(new BC_MenuItem("224"));
1518                 add_item(new BC_MenuItem("256"));
1519                 add_item(new BC_MenuItem("320"));
1520         }
1523 int MPEGABitrate::handle_event()
1525         gui->asset->ampeg_bitrate = string_to_bitrate(get_text());
1526         return 1;
1529 int MPEGABitrate::string_to_bitrate(char *string)
1531         return atol(string);
1535 char* MPEGABitrate::bitrate_to_string(char *string, int bitrate)
1537         sprintf(string, "%d", bitrate);
1538         return string;
1549 MPEGConfigVideo::MPEGConfigVideo(BC_WindowBase *parent_window, 
1550         Asset *asset)
1551  : BC_Window(PROGRAM_NAME ": Video Compression",
1552         parent_window->get_abs_cursor_x(1),
1553         parent_window->get_abs_cursor_y(1),
1554         500,
1555         400,
1556         -1,
1557         -1,
1558         0,
1559         0,
1560         1)
1562         this->parent_window = parent_window;
1563         this->asset = asset;
1564         reset_cmodel();
1567 MPEGConfigVideo::~MPEGConfigVideo()
1571 int MPEGConfigVideo::create_objects()
1573         int x = 10, y = 10;
1574         int x1 = x + 150;
1575         int x2 = x + 300;
1578         add_subwindow(new BC_Title(x, y, _("Color model:")));
1579         add_subwindow(cmodel = new MPEGColorModel(x1, y, this));
1580         cmodel->create_objects();
1581         y += 30;
1583         update_cmodel_objs();
1585         add_subwindow(new BC_OKButton(this));
1586         show_window();
1587         flush();
1588         return 0;
1591 int MPEGConfigVideo::close_event()
1593         set_done(0);
1594         return 1;
1598 void MPEGConfigVideo::delete_cmodel_objs()
1600         delete preset;
1601         delete derivative;
1602         delete bitrate;
1603         delete fixed_bitrate;
1604         delete quant;
1605         delete fixed_quant;
1606         delete iframe_distance;
1607         delete pframe_distance;
1608         delete top_field_first;
1609         delete progressive;
1610         delete denoise;
1611         delete seq_codes;
1612         titles.remove_all_objects();
1613         reset_cmodel();
1616 void MPEGConfigVideo::reset_cmodel()
1618         preset = 0;
1619         derivative = 0;
1620         bitrate = 0;
1621         fixed_bitrate = 0;
1622         quant = 0;
1623         fixed_quant = 0;
1624         iframe_distance = 0;
1625         pframe_distance = 0;
1626         top_field_first = 0;
1627         progressive = 0;
1628         denoise = 0;
1629         seq_codes = 0;
1632 void MPEGConfigVideo::update_cmodel_objs()
1634         BC_Title *title;
1635         int x = 10;
1636         int y = 40;
1637         int x1 = x + 150;
1638         int x2 = x + 280;
1640         delete_cmodel_objs();
1642         if(asset->vmpeg_cmodel == MPEG_YUV420)
1643         {
1644                 add_subwindow(title = new BC_Title(x, y + 5, _("Format Preset:")));
1645                 titles.append(title);
1646                 add_subwindow(preset = new MPEGPreset(x1, y, this));
1647                 preset->create_objects();
1648                 y += 30;
1649         }
1651         add_subwindow(title = new BC_Title(x, y + 5, _("Derivative:")));
1652         titles.append(title);
1653         add_subwindow(derivative = new MPEGDerivative(x1, y, this));
1654         derivative->create_objects();
1655         y += 30;
1657         add_subwindow(title = new BC_Title(x, y + 5, _("Bitrate:")));
1658         titles.append(title);
1659         add_subwindow(bitrate = new MPEGBitrate(x1, y, this));
1660         add_subwindow(fixed_bitrate = new MPEGFixedBitrate(x2, y, this));
1661         y += 30;
1663         add_subwindow(title = new BC_Title(x, y, _("Quantization:")));
1664         titles.append(title);
1665         quant = new MPEGQuant(x1, y, this);
1666         quant->create_objects();
1667         add_subwindow(fixed_quant = new MPEGFixedQuant(x2, y, this));
1668         y += 30;
1670         add_subwindow(title = new BC_Title(x, y, _("I frame distance:")));
1671         titles.append(title);
1672         iframe_distance = new MPEGIFrameDistance(x1, y, this);
1673         iframe_distance->create_objects();
1674         y += 30;
1676         if(asset->vmpeg_cmodel == MPEG_YUV420)
1677         {
1678                 add_subwindow(title = new BC_Title(x, y, _("P frame distance:")));
1679                 titles.append(title);
1680                 pframe_distance = new MPEGPFrameDistance(x1, y, this);
1681                 pframe_distance->create_objects();
1682                 y += 30;
1684                 add_subwindow(top_field_first = new BC_CheckBox(x, y, &asset->vmpeg_field_order, _("Bottom field first")));
1685                 y += 30;
1686         }
1688         add_subwindow(progressive = new BC_CheckBox(x, y, &asset->vmpeg_progressive, _("Progressive frames")));
1689         y += 30;
1690         add_subwindow(denoise = new BC_CheckBox(x, y, &asset->vmpeg_denoise, _("Denoise")));
1691         y += 30;
1692         add_subwindow(seq_codes = new BC_CheckBox(x, y, &asset->vmpeg_seq_codes, _("Sequence start codes in every GOP")));
1708 MPEGDerivative::MPEGDerivative(int x, int y, MPEGConfigVideo *gui)
1709  : BC_PopupMenu(x, y, 150, derivative_to_string(gui->asset->vmpeg_derivative))
1711         this->gui = gui;
1714 void MPEGDerivative::create_objects()
1716         add_item(new BC_MenuItem(derivative_to_string(1)));
1717         add_item(new BC_MenuItem(derivative_to_string(2)));
1720 int MPEGDerivative::handle_event()
1722         gui->asset->vmpeg_derivative = string_to_derivative(get_text());
1723         return 1;
1726 int MPEGDerivative::string_to_derivative(char *string)
1728         if(!strcasecmp(derivative_to_string(1), string))
1729                 return 1;
1730         if(!strcasecmp(derivative_to_string(2), string))
1731                 return 2;
1733         return 1;
1736 char* MPEGDerivative::derivative_to_string(int derivative)
1738         switch(derivative)
1739         {
1740                 case 1:
1741                         return _("MPEG-1");
1742                         break;
1743                 
1744                 case 2:
1745                         return _("MPEG-2");
1746                         break;
1747                         
1748                 default:
1749                         return _("MPEG-1");
1750                         break;
1751         }
1764 MPEGPreset::MPEGPreset(int x, int y, MPEGConfigVideo *gui)
1765  : BC_PopupMenu(x, y, 200, value_to_string(gui->asset->vmpeg_preset))
1767         this->gui = gui;
1770 void MPEGPreset::create_objects()
1772         for(int i = 0; i < 10; i++)
1773         {
1774                 add_item(new BC_MenuItem(value_to_string(i)));
1775         }
1778 int MPEGPreset::handle_event()
1780         gui->asset->vmpeg_preset = string_to_value(get_text());
1781         return 1;
1784 int MPEGPreset::string_to_value(char *string)
1786         for(int i = 0; i < 10; i++)
1787         {
1788                 if(!strcasecmp(value_to_string(i), string))
1789                         return i;
1790         }
1791         return 0;
1794 char* MPEGPreset::value_to_string(int derivative)
1796         switch(derivative)
1797         {
1798                 case 0: return _("Generic MPEG-1"); break;
1799                 case 1: return _("standard VCD"); break;
1800                 case 2: return _("user VCD"); break;
1801                 case 3: return _("Generic MPEG-2"); break;
1802                 case 4: return _("standard SVCD"); break;
1803                 case 5: return _("user SVCD"); break;
1804                 case 6: return _("VCD Still sequence"); break;
1805                 case 7: return _("SVCD Still sequence"); break;
1806                 case 8: return _("DVD NAV"); break;
1807                 case 9: return _("DVD"); break;
1808                 default: return _("Generic MPEG-1"); break;
1809         }
1822 MPEGBitrate::MPEGBitrate(int x, int y, MPEGConfigVideo *gui)
1823  : BC_TextBox(x, y, 100, 1, gui->asset->vmpeg_bitrate)
1825         this->gui = gui;
1829 int MPEGBitrate::handle_event()
1831         gui->asset->vmpeg_bitrate = atol(get_text());
1832         return 1;
1839 MPEGQuant::MPEGQuant(int x, int y, MPEGConfigVideo *gui)
1840  : BC_TumbleTextBox(gui, 
1841         (int64_t)gui->asset->vmpeg_quantization, 
1842         (int64_t)1,
1843         (int64_t)100,
1844         x, 
1845         y,
1846         100)
1848         this->gui = gui;
1851 int MPEGQuant::handle_event()
1853         gui->asset->vmpeg_quantization = atol(get_text());
1854         return 1;
1857 MPEGFixedBitrate::MPEGFixedBitrate(int x, int y, MPEGConfigVideo *gui)
1858  : BC_Radial(x, y, gui->asset->vmpeg_fix_bitrate, _("Fixed bitrate"))
1860         this->gui = gui;
1863 int MPEGFixedBitrate::handle_event()
1865         update(1);
1866         gui->asset->vmpeg_fix_bitrate = 1;
1867         gui->fixed_quant->update(0);
1868         return 1;
1871 MPEGFixedQuant::MPEGFixedQuant(int x, int y, MPEGConfigVideo *gui)
1872  : BC_Radial(x, y, !gui->asset->vmpeg_fix_bitrate, _("Fixed quantization"))
1874         this->gui = gui;
1877 int MPEGFixedQuant::handle_event()
1879         update(1);
1880         gui->asset->vmpeg_fix_bitrate = 0;
1881         gui->fixed_bitrate->update(0);
1882         return 1;
1893 MPEGIFrameDistance::MPEGIFrameDistance(int x, int y, MPEGConfigVideo *gui)
1894  : BC_TumbleTextBox(gui, 
1895         (int64_t)gui->asset->vmpeg_iframe_distance, 
1896         (int64_t)1,
1897         (int64_t)100,
1898         x, 
1899         y,
1900         50)
1902         this->gui = gui;
1905 int MPEGIFrameDistance::handle_event()
1907         gui->asset->vmpeg_iframe_distance = atoi(get_text());
1908         return 1;
1917 MPEGPFrameDistance::MPEGPFrameDistance(int x, int y, MPEGConfigVideo *gui)
1918  : BC_TumbleTextBox(gui, 
1919         (int64_t)gui->asset->vmpeg_pframe_distance, 
1920         (int64_t)0,
1921         (int64_t)2,
1922         x, 
1923         y,
1924         50)
1926         this->gui = gui;
1929 int MPEGPFrameDistance::handle_event()
1931         gui->asset->vmpeg_pframe_distance = atoi(get_text());
1932         return 1;
1942 MPEGColorModel::MPEGColorModel(int x, int y, MPEGConfigVideo *gui)
1943  : BC_PopupMenu(x, y, 150, cmodel_to_string(gui->asset->vmpeg_cmodel))
1945         this->gui = gui;
1948 void MPEGColorModel::create_objects()
1950         add_item(new BC_MenuItem(cmodel_to_string(0)));
1951         add_item(new BC_MenuItem(cmodel_to_string(1)));
1954 int MPEGColorModel::handle_event()
1956         gui->asset->vmpeg_cmodel = string_to_cmodel(get_text());
1957         gui->update_cmodel_objs();
1958         return 1;
1961 int MPEGColorModel::string_to_cmodel(char *string)
1963         if(!strcasecmp(cmodel_to_string(0), string))
1964                 return 0;
1965         if(!strcasecmp(cmodel_to_string(1), string))
1966                 return 1;
1967         return 1;
1970 char* MPEGColorModel::cmodel_to_string(int cmodel)
1972         switch(cmodel)
1973         {
1974                 case MPEG_YUV420:
1975                         return _("YUV 4:2:0");
1976                         break;
1977                 
1978                 case MPEG_YUV422:
1979                         return _("YUV 4:2:2");
1980                         break;
1981                         
1982                 default:
1983                         return _("YUV 4:2:0");
1984                         break;
1985         }