r665: Merged the official release 2.0.
[cinelerra_cv.git] / cinelerra / filempeg.C
blobfa4928cc163cf10c614a545a209c700c935db462
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         int result = 0;
148         this->rd = rd;
149         this->wr = wr;
151         if(rd)
152         {
153                 if(!(fd = mpeg3_open(asset->path)))
154                 {
155                         printf("FileMPEG::open_file %s\n", asset->path);
156                         result = 1;
157                 }
158                 else
159                 {
160 // Determine if the file needs a table of contents and create one if needed.
161                         if(!mpeg3_has_toc(fd))
162                         {
163 // If it has video it must be scanned since video has keyframes.
164                                 if(mpeg3_total_vstreams(fd))
165                                 {
166                                         if(create_index()) return 1;
167                                 }
168                         }
170                         mpeg3_set_cpus(fd, file->cpus);
172                         asset->audio_data = mpeg3_has_audio(fd);
173                         if(asset->audio_data)
174                         {
175                                 asset->channels = 0;
176                                 for(int i = 0; i < mpeg3_total_astreams(fd); i++)
177                                 {
178                                         asset->channels += mpeg3_audio_channels(fd, i);
179                                 }
180                                 if(!asset->sample_rate)
181                                         asset->sample_rate = mpeg3_sample_rate(fd, 0);
182                                 asset->audio_length = mpeg3_audio_samples(fd, 0); 
183                         }
185                         asset->video_data = mpeg3_has_video(fd);
186                         if(asset->video_data)
187                         {
188                                 asset->layers = mpeg3_total_vstreams(fd);
189                                 asset->width = mpeg3_video_width(fd, 0);
190                                 asset->height = mpeg3_video_height(fd, 0);
191                                 asset->interlace_mode = BC_ILACE_MODE_UNDETECTED; // TODO: (to do this, start at hvirtualcvs/libmpeg3/headers.c 
192                                                                                   //        and find out how to decode info from the header)
193                                 asset->video_length = mpeg3_video_frames(fd, 0);
194                                 asset->vmpeg_cmodel = 
195                                         (mpeg3_colormodel(fd, 0) == MPEG3_YUV422P) ? MPEG_YUV422 : MPEG_YUV420;
196                                 if(!asset->frame_rate)
197                                         asset->frame_rate = mpeg3_frame_rate(fd, 0);
198                         }
199                 }
200         }
201         
202         
203         
204         if(wr && asset->format == FILE_VMPEG)
205         {
206 // Heroine Virtual encoder
207                 if(asset->vmpeg_cmodel == MPEG_YUV422)
208                 {
209                         char bitrate_string[BCTEXTLEN];
210                         char quant_string[BCTEXTLEN];
211                         char iframe_string[BCTEXTLEN];
213                         sprintf(bitrate_string, "%d", asset->vmpeg_bitrate);
214                         sprintf(quant_string, "%d", asset->vmpeg_quantization);
215                         sprintf(iframe_string, "%d", asset->vmpeg_iframe_distance);
217 // Construct command line
218                         if(!result)
219                         {
220                                 append_vcommand_line("mpeg2enc");
223                                 if(asset->aspect_ratio > 0)
224                                 {
225                                         append_vcommand_line("-a");
226                                         if(EQUIV(asset->aspect_ratio, 1))
227                                                 append_vcommand_line("1");
228                                         else
229                                         if(EQUIV(asset->aspect_ratio, 1.333))
230                                                 append_vcommand_line("2");
231                                         else
232                                         if(EQUIV(asset->aspect_ratio, 1.777))
233                                                 append_vcommand_line("3");
234                                         else
235                                         if(EQUIV(asset->aspect_ratio, 2.11))
236                                                 append_vcommand_line("4");
237                                 }
239                                 append_vcommand_line(asset->vmpeg_derivative == 1 ? "-1" : "");
240                                 append_vcommand_line(asset->vmpeg_cmodel == MPEG_YUV422 ? "-422" : "");
241                                 if(asset->vmpeg_fix_bitrate)
242                                 {
243                                         append_vcommand_line("-b");
244                                         append_vcommand_line(bitrate_string);
245                                 }
246                                 else
247                                 {
248                                         append_vcommand_line("-q");
249                                         append_vcommand_line(quant_string);
250                                 }
251                                 append_vcommand_line(!asset->vmpeg_fix_bitrate ? quant_string : "");
252                                 append_vcommand_line("-n");
253                                 append_vcommand_line(iframe_string);
254                                 append_vcommand_line(asset->vmpeg_progressive ? "-p" : "");
255                                 append_vcommand_line(asset->vmpeg_denoise ? "-d" : "");
256                                 append_vcommand_line(file->cpus <= 1 ? "-u" : "");
257                                 append_vcommand_line(asset->vmpeg_seq_codes ? "-g" : "");
258                                 append_vcommand_line(asset->path);
260                                 video_out = new FileMPEGVideo(this);
261                                 video_out->start();
262                         }
263                 }
264                 else
265 // mjpegtools encoder
266                 {
267                         char string[BCTEXTLEN];
268                         sprintf(mjpeg_command, MJPEG_EXE);
270                         if(asset->vmpeg_fix_bitrate)
271                         {
272                                 sprintf(string, " -b %d -q %d", asset->vmpeg_bitrate, 0);
273                         }
274                         else
275                         {
276                                 sprintf(string, " -b %d -q %d", asset->vmpeg_bitrate, asset->vmpeg_quantization);
277                         }
278                         strcat(mjpeg_command, string);
285 // Aspect ratio
286                         int aspect_ratio_code = -1;
287                         if(asset->aspect_ratio > 0)
288                         {
289                                 for(int i = 0; i < sizeof(aspect_ratio_codes) / sizeof(double); i++)
290                                 {
291                                         if(EQUIV(aspect_ratio_codes[i], asset->aspect_ratio))
292                                         {
293                                                 aspect_ratio_code = i;
294                                                 break;
295                                         }
296                                 }
297                         }
298                         if(aspect_ratio_code < 0)
299                         {
300                                 printf("FileMPEG::open_file: Unsupported aspect ratio %f\n", asset->aspect_ratio);
301                                 aspect_ratio_code = 2;
302                         }
303                         sprintf(string, " -a %d", aspect_ratio_code);
304                         strcat(mjpeg_command, string);
311 // Frame rate
312                         int frame_rate_code = -1;
313                 for(int i = 1; sizeof(frame_rate_codes) / sizeof(double); ++i)
314                         {
315                                 if(EQUIV(asset->frame_rate, frame_rate_codes[i]))
316                                 {
317                                         frame_rate_code = i;
318                                         break;
319                                 }
320                         }
321                         if(frame_rate_code < 0)
322                         {
323                                 frame_rate_code = 4;
324                                 printf("FileMPEG::open_file: Unsupported frame rate %f\n", asset->frame_rate);
325                         }
326                         sprintf(string, " -F %d", frame_rate_code);
327                         strcat(mjpeg_command, string);
333                         strcat(mjpeg_command, asset->vmpeg_progressive ? " -I 0" : " -I 1");
334                         
337                         sprintf(string, " -M %d", file->cpus);
338                         strcat(mjpeg_command, string);
341                         if(!asset->vmpeg_progressive)
342                         {
343                                 strcat(mjpeg_command, asset->vmpeg_field_order ? " -z b" : " -z t");
344                         }
347                         sprintf(string, " -f %d", asset->vmpeg_preset);
348                         strcat(mjpeg_command, string);
351                         sprintf(string, " -g %d -G %d", asset->vmpeg_iframe_distance, asset->vmpeg_iframe_distance);
352                         strcat(mjpeg_command, string);
355                         if(asset->vmpeg_seq_codes) strcat(mjpeg_command, " -s");
358                         sprintf(string, " -R %d", CLAMP(asset->vmpeg_pframe_distance, 0, 2));
359                         strcat(mjpeg_command, string);
361                         sprintf(string, " -o %s", asset->path);
362                         strcat(mjpeg_command, string);
366                         printf("FileMPEG::open_file: Running %s\n", mjpeg_command);
367                         if(!(mjpeg_out = popen(mjpeg_command, "w")))
368                         {
369                                 perror("FileMPEG::open_file");
370                         }
372                         video_out = new FileMPEGVideo(this);
373                         video_out->start();
374                 }
375         }
377         if(wr && asset->format == FILE_AMPEG)
378         {
379                 char command_line[BCTEXTLEN];
380                 char encoder_string[BCTEXTLEN];
381                 char argument_string[BCTEXTLEN];
383 //printf("FileMPEG::open_file 1 %d\n", asset->ampeg_derivative);
384                 encoder_string[0] = 0;
386                 if(asset->ampeg_derivative == 2)
387                 {
388                         char string[BCTEXTLEN];
389                         append_acommand_line("toolame");
390                         append_acommand_line("-m");
391                         append_acommand_line((asset->channels >= 2) ? "j" : "m");
392                         sprintf(string, "%f", (float)asset->sample_rate / 1000);
393                         append_acommand_line("-s");
394                         append_acommand_line(string);
395                         sprintf(string, "%d", asset->ampeg_bitrate);
396                         append_acommand_line("-b");
397                         append_acommand_line(string);
398                         append_acommand_line("-");
399                         append_acommand_line(asset->path);
401                         audio_out = new FileMPEGAudio(this);
402                         audio_out->start();
403                 }
404                 else
405                 if(asset->ampeg_derivative == 3)
406                 {
407                         lame_global = lame_init();
408                         lame_set_brate(lame_global, asset->ampeg_bitrate / 1000);
409                         lame_set_quality(lame_global, 0);
410                         lame_set_in_samplerate(lame_global, 
411                                 asset->sample_rate);
412                         if((result = lame_init_params(lame_global)) < 0)
413                         {
414                                 printf(_("encode: lame_init_params returned %d\n"), result);
415                                 lame_close(lame_global);
416                                 lame_global = 0;
417                         }
418                         else
419                         if(!(lame_fd = fopen(asset->path, "w")))
420                         {
421                                 perror("FileMPEG::open_file");
422                                 lame_close(lame_global);
423                                 lame_global = 0;
424                         }
425                 }
426                 else
427                 {
428                         printf("FileMPEG::open_file: ampeg_derivative=%d\n", asset->ampeg_derivative);
429                         result = 1;
430                 }
431         }
433 //asset->dump();
434 //printf("FileMPEG::open_file 100\n");
435         return result;
445 int FileMPEG::create_index()
447 // Calculate TOC path
448         char index_filename[BCTEXTLEN];
449         char source_filename[BCTEXTLEN];
450         IndexFile::get_index_filename(source_filename, 
451                 file->preferences->index_directory, 
452                 index_filename, 
453                 asset->path);
454         char *ptr = strrchr(index_filename, '.');
455         if(!ptr) return 1;
457         sprintf(ptr, ".toc");
459 // Test existence of TOC
460         FILE *test = fopen(index_filename, "r");
461         if(test)
462         {
463 // Reopen with table of contents
464                 fclose(test);
465         }
466         else
467         {
468 // Create progress window.
469 // This gets around the fact that MWindowGUI is locked.
470                 char progress_title[BCTEXTLEN];
471                 char string[BCTEXTLEN];
472                 sprintf(progress_title, "Creating %s\n", index_filename);
473                 int64_t total_bytes;
474                 mpeg3_t *index_file = mpeg3_start_toc(asset->path, index_filename, &total_bytes);
475                 struct timeval new_time;
476                 struct timeval prev_time;
477                 struct timeval start_time;
478                 struct timeval current_time;
479                 gettimeofday(&prev_time, 0);
480                 gettimeofday(&start_time, 0);
482                 BC_ProgressBox *progress = new BC_ProgressBox(-1, 
483                         -1, 
484                         progress_title, 
485                         total_bytes);
486                 progress->start();
487                 int result = 0;
488                 while(1)
489                 {
490                         int64_t bytes_processed;
491                         mpeg3_do_toc(index_file, &bytes_processed);
492                         gettimeofday(&new_time, 0);
494                         if(new_time.tv_sec - prev_time.tv_sec >= 1)
495                         {
496                                 gettimeofday(&current_time, 0);
497                                 int64_t elapsed_seconds = current_time.tv_sec - start_time.tv_sec;
498                                 int64_t total_seconds = elapsed_seconds * total_bytes / bytes_processed;
499                                 int64_t eta = total_seconds - elapsed_seconds;
500                                 progress->update(bytes_processed, 1);
501                                 sprintf(string, 
502                                         "%sETA: %lldm%llds",
503                                         progress_title,
504                                         eta / 60,
505                                         eta % 60);
506                                 progress->update_title(string, 1);
507 //                              fprintf(stderr, "ETA: %dm%ds        \r", 
508 //                                      bytes_processed * 100 / total_bytes,
509 //                                      eta / 60,
510 //                                      eta % 60);
511 //                              fflush(stdout);
512                                 prev_time = new_time;
513                         }
514                         if(bytes_processed >= total_bytes) break;
515                         if(progress->is_cancelled()) 
516                         {
517                                 result = 1;
518                                 break;
519                         }
520                 }
522                 mpeg3_stop_toc(index_file);
524                 progress->stop_progress();
525                 delete progress;
526                 if(result)
527                 {
528                         remove(index_filename);
529                         return 1;
530                 }
531         }
534 // Failed
536 // Reopen file from index path instead of asset path.
537         if(fd) mpeg3_close(fd);
538         if(!(fd = mpeg3_open(index_filename)))
539         {
540                 return 1;
541         }
542         else
543                 return 0;
551 void FileMPEG::append_vcommand_line(const char *string)
553         if(string[0])
554         {
555                 char *argv = strdup(string);
556                 vcommand_line.append(argv);
557         }
560 void FileMPEG::append_acommand_line(const char *string)
562         if(string[0])
563         {
564                 char *argv = strdup(string);
565                 acommand_line.append(argv);
566         }
570 int FileMPEG::close_file()
572         mjpeg_eof = 1;
573         next_frame_lock->unlock();
575         if(fd)
576         {
577                 mpeg3_close(fd);
578         }
580         if(video_out)
581         {
582 // End of sequence signal
583                 if(file->asset->vmpeg_cmodel == MPEG_YUV422)
584                 {
585                         mpeg2enc_set_input_buffers(1, 0, 0, 0);
586                 }
587                 delete video_out;
588                 video_out = 0;
589         }
591         vcommand_line.remove_all_objects();
592         acommand_line.remove_all_objects();
594         if(audio_out)
595         {
596                 toolame_send_buffer(0, 0);
597                 delete audio_out;
598                 audio_out = 0;
599         }
601         if(lame_global)
602                 lame_close(lame_global);
604         if(temp_frame) delete temp_frame;
605         if(toolame_temp) delete [] toolame_temp;
607         if(lame_temp[0]) delete [] lame_temp[0];
608         if(lame_temp[1]) delete [] lame_temp[1];
609         if(lame_output) delete [] lame_output;
610         if(lame_fd) fclose(lame_fd);
612         if(mjpeg_out) fclose(mjpeg_out);
613         reset_parameters();
615         FileBase::close_file();
616         return 0;
619 int FileMPEG::get_best_colormodel(Asset *asset, int driver)
621 //printf("FileMPEG::get_best_colormodel 1\n");
622         switch(driver)
623         {
624                 case PLAYBACK_X11:
625                         return BC_RGB888;
626                         if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
627                         if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
628                         break;
629                 case PLAYBACK_X11_XV:
630                         if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
631                         if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
632                         break;
633                 case PLAYBACK_LML:
634                 case PLAYBACK_BUZ:
635                         return BC_YUV422P;
636                         break;
637                 case PLAYBACK_DV1394:
638                 case PLAYBACK_FIREWIRE:
639                         return BC_YUV422P;
640                         break;
641                 case VIDEO4LINUX:
642                 case VIDEO4LINUX2:
643                         if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
644                         if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
645                         break;
646                 case CAPTURE_BUZ:
647                 case CAPTURE_LML:
648                         return BC_YUV422;
649                         break;
650                 case CAPTURE_FIREWIRE:
651                 case CAPTURE_IEC61883:
652                         return BC_YUV422P;
653                         break;
654         }
655 //printf("FileMPEG::get_best_colormodel 100\n");
658 int FileMPEG::colormodel_supported(int colormodel)
660         return colormodel;
663 int FileMPEG::get_index(char *index_path)
665         if(!fd) return 1;
668 // Convert the index tables from tracks to channels.
669         if(mpeg3_index_tracks(fd))
670         {
671 // Calculate size of buffer needed for all channels
672                 int buffer_size = 0;
673                 for(int i = 0; i < mpeg3_index_tracks(fd); i++)
674                 {
675                         buffer_size += mpeg3_index_size(fd, i) *
676                                 mpeg3_index_channels(fd, i) *
677                                 2;
678                 }
680                 asset->index_buffer = new float[buffer_size];
682 // Size of index buffer in floats
683                 int current_offset = 0;
684 // Current asset channel
685                 int current_channel = 0;
686                 asset->index_zoom = mpeg3_index_zoom(fd);
687                 asset->index_offsets = new int64_t[asset->channels];
688                 asset->index_sizes = new int64_t[asset->channels];
689                 for(int i = 0; i < mpeg3_index_tracks(fd); i++)
690                 {
691                         for(int j = 0; j < mpeg3_index_channels(fd, i); j++)
692                         {
693                                 asset->index_offsets[current_channel] = current_offset;
694                                 asset->index_sizes[current_channel] = mpeg3_index_size(fd, i) * 2;
695                                 memcpy(asset->index_buffer + current_offset,
696                                         mpeg3_index_data(fd, i, j),
697                                         mpeg3_index_size(fd, i) * sizeof(float) * 2);
699                                 current_offset += mpeg3_index_size(fd, i) * 2;
700                                 current_channel++;
701                         }
702                 }
704                 FileSystem fs;
705                 asset->index_bytes = fs.get_size(asset->path);
707                 asset->write_index(index_path, buffer_size * sizeof(float));
708                 delete [] asset->index_buffer;
710                 return 0;
711         }
713         return 1;
717 int FileMPEG::can_copy_from(Edit *edit, int64_t position)
719         if(!fd) return 0;
720         return 0;
723 int FileMPEG::set_audio_position(int64_t sample)
725 #if 0
726         if(!fd) return 1;
727         
728         int channel, stream;
729         to_streamchannel(file->current_channel, stream, channel);
731 //printf("FileMPEG::set_audio_position %d %d %d\n", sample, mpeg3_get_sample(fd, stream), last_sample);
732         if(sample != mpeg3_get_sample(fd, stream) &&
733                 sample != last_sample)
734         {
735                 if(sample >= 0 && sample < asset->audio_length)
736                 {
737 //printf("FileMPEG::set_audio_position seeking stream %d\n", sample);
738                         return mpeg3_set_sample(fd, sample, stream);
739                 }
740                 else
741                         return 1;
742         }
743 #endif
744         return 0;
747 int FileMPEG::set_video_position(int64_t x)
749         if(!fd) return 1;
750         if(x >= 0 && x < asset->video_length)
751         {
752                 mpeg3_set_frame(fd, x, file->current_layer);
753         }
754         else
755                 return 1;
759 int FileMPEG::write_samples(double **buffer, int64_t len)
761         int result = 0;
763 //printf("FileMPEG::write_samples 1\n");
764         if(asset->ampeg_derivative == 2)
765         {
766 // Convert to int16
767                 int channels = MIN(asset->channels, 2);
768                 int64_t audio_size = len * channels * 2;
769                 if(toolame_allocation < audio_size)
770                 {
771                         if(toolame_temp) delete [] toolame_temp;
772                         toolame_temp = new unsigned char[audio_size];
773                         toolame_allocation = audio_size;
774                 }
776                 for(int i = 0; i < channels; i++)
777                 {
778                         int16_t *output = ((int16_t*)toolame_temp) + i;
779                         double *input = buffer[i];
780                         for(int j = 0; j < len; j++)
781                         {
782                                 int sample = (int)(*input * 0x7fff);
783                                 *output = (int16_t)(CLIP(sample, -0x8000, 0x7fff));
784                                 output += channels;
785                                 input++;
786                         }
787                 }
788                 result = toolame_send_buffer((char*)toolame_temp, audio_size);
789         }
790         else
791         if(asset->ampeg_derivative == 3)
792         {
793                 int channels = MIN(asset->channels, 2);
794                 int64_t audio_size = len * channels;
795                 if(!lame_global) return 1;
796                 if(!lame_fd) return 1;
797                 if(lame_allocation < audio_size)
798                 {
799                         if(lame_temp[0]) delete [] lame_temp[0];
800                         if(lame_temp[1]) delete [] lame_temp[1];
801                         lame_temp[0] = new float[audio_size];
802                         lame_temp[1] = new float[audio_size];
803                         lame_allocation = audio_size;
804                 }
806                 if(lame_output_allocation < audio_size * 4)
807                 {
808                         if(lame_output) delete [] lame_output;
809                         lame_output_allocation = audio_size * 4;
810                         lame_output = new char[lame_output_allocation];
811                 }
813                 for(int i = 0; i < channels; i++)
814                 {
815                         float *output = lame_temp[i];
816                         double *input = buffer[i];
817                         for(int j = 0; j < len; j++)
818                         {
819                                 *output++ = *input++ * (float)32768;
820                         }
821                 }
823                 result = lame_encode_buffer_float(lame_global,
824                         lame_temp[0],
825                         (channels > 1) ? lame_temp[1] : lame_temp[0],
826                         len,
827                         (unsigned char*)lame_output,
828                         lame_output_allocation);
829                 if(result > 0)
830                 {
831                         char *real_output = lame_output;
832                         int bytes = result;
833                         if(!lame_started)
834                         {
835                                 for(int i = 0; i < bytes; i++)
836                                         if(lame_output[i])
837                                         {
838                                                 real_output = &lame_output[i];
839                                                 lame_started = 1;
840                                                 bytes -= i;
841                                                 break;
842                                         }
843                         }
844                         if(bytes > 0 && lame_started)
845                         {
846                                 result = !fwrite(real_output, 1, bytes, lame_fd);
847                                 if(result)
848                                         perror("FileMPEG::write_samples");
849                         }
850                         else
851                                 result = 0;
852                 }
853                 else
854                         result = 1;
855         }
857         return result;
860 int FileMPEG::write_frames(VFrame ***frames, int len)
862         int result = 0;
864         if(video_out)
865         {
866                 int temp_w = (int)((asset->width + 15) / 16) * 16;
867                 int temp_h;
870                 int output_cmodel = 
871                         (asset->vmpeg_cmodel == MPEG_YUV420) ? BC_YUV420P : BC_YUV422P;
872                 
873                 
874 // Height depends on progressiveness
875                 if(asset->vmpeg_progressive || asset->vmpeg_derivative == 1)
876                         temp_h = (int)((asset->height + 15) / 16) * 16;
877                 else
878                         temp_h = (int)((asset->height + 31) / 32) * 32;
880 //printf("FileMPEG::write_frames 1\n");
881                 
882 // Only 1 layer is supported in MPEG output
883                 for(int i = 0; i < 1; i++)
884                 {
885                         for(int j = 0; j < len && !result; j++)
886                         {
887                                 VFrame *frame = frames[i][j];
888                                 
889                                 
890                                 
891                                 if(asset->vmpeg_cmodel == MPEG_YUV422)
892                                 {
893                                         if(frame->get_w() == temp_w &&
894                                                 frame->get_h() == temp_h &&
895                                                 frame->get_color_model() == output_cmodel)
896                                         {
897                                                 mpeg2enc_set_input_buffers(0, 
898                                                         (char*)frame->get_y(),
899                                                         (char*)frame->get_u(),
900                                                         (char*)frame->get_v());
901                                         }
902                                         else
903                                         {
904                                                 if(temp_frame &&
905                                                         (temp_frame->get_w() != temp_w ||
906                                                         temp_frame->get_h() != temp_h ||
907                                                         temp_frame->get_color_model() || output_cmodel))
908                                                 {
909                                                         delete temp_frame;
910                                                         temp_frame = 0;
911                                                 }
914                                                 if(!temp_frame)
915                                                 {
916                                                         temp_frame = new VFrame(0, 
917                                                                 temp_w, 
918                                                                 temp_h, 
919                                                                 output_cmodel);
920                                                 }
922                                                 cmodel_transfer(temp_frame->get_rows(), 
923                                                         frame->get_rows(),
924                                                         temp_frame->get_y(),
925                                                         temp_frame->get_u(),
926                                                         temp_frame->get_v(),
927                                                         frame->get_y(),
928                                                         frame->get_u(),
929                                                         frame->get_v(),
930                                                         0,
931                                                         0,
932                                                         asset->width,
933                                                         asset->height,
934                                                         0,
935                                                         0,
936                                                         asset->width,
937                                                         asset->height,
938                                                         frame->get_color_model(), 
939                                                         temp_frame->get_color_model(),
940                                                         0, 
941                                                         frame->get_w(),
942                                                         temp_w);
944                                                 mpeg2enc_set_input_buffers(0, 
945                                                         (char*)temp_frame->get_y(),
946                                                         (char*)temp_frame->get_u(),
947                                                         (char*)temp_frame->get_v());
948                                         }
949                                 }
950                                 else
951                                 {
952 // MJPEG uses the same dimensions as the input
953                                         if(frame->get_color_model() == output_cmodel)
954                                         {
955                                                 mjpeg_y = frame->get_y();
956                                                 mjpeg_u = frame->get_u();
957                                                 mjpeg_v = frame->get_v();
958                                         }
959                                         else
960                                         {
961                                                 if(!temp_frame)
962                                                 {
963                                                         temp_frame = new VFrame(0, 
964                                                                 asset->width, 
965                                                                 asset->height, 
966                                                                 output_cmodel);
967                                                 }
969                                                 cmodel_transfer(temp_frame->get_rows(), 
970                                                         frame->get_rows(),
971                                                         temp_frame->get_y(),
972                                                         temp_frame->get_u(),
973                                                         temp_frame->get_v(),
974                                                         frame->get_y(),
975                                                         frame->get_u(),
976                                                         frame->get_v(),
977                                                         0,
978                                                         0,
979                                                         asset->width,
980                                                         asset->height,
981                                                         0,
982                                                         0,
983                                                         asset->width,
984                                                         asset->height,
985                                                         frame->get_color_model(), 
986                                                         temp_frame->get_color_model(),
987                                                         0, 
988                                                         frame->get_w(),
989                                                         temp_w);
991                                                 mjpeg_y = temp_frame->get_y();
992                                                 mjpeg_u = temp_frame->get_u();
993                                                 mjpeg_v = temp_frame->get_v();
994                                         }
999                                         next_frame_lock->unlock();
1000                                         next_frame_done->lock("FileMPEG::write_frames");
1001                                         if(mjpeg_error) result = 1;
1002                                 }
1008                         }
1009                 }
1010         }
1014         return result;
1017 int FileMPEG::read_frame(VFrame *frame)
1019         if(!fd) return 1;
1020         int result = 0;
1021         int src_cmodel;
1023 SET_TRACE
1024         if(mpeg3_colormodel(fd, 0) == MPEG3_YUV420P)
1025                 src_cmodel = BC_YUV420P;
1026         else
1027         if(mpeg3_colormodel(fd, 0) == MPEG3_YUV422P)
1028                 src_cmodel = BC_YUV422P;
1030 SET_TRACE
1031         switch(frame->get_color_model())
1032         {
1033                 case MPEG3_RGB565:
1034                 case MPEG3_BGR888:
1035                 case MPEG3_BGRA8888:
1036                 case MPEG3_RGB888:
1037                 case MPEG3_RGBA8888:
1038                 case MPEG3_RGBA16161616:
1039                         mpeg3_read_frame(fd, 
1040                                         frame->get_rows(), /* Array of pointers to the start of each output row */
1041                                         0,                    /* Location in input frame to take picture */
1042                                         0, 
1043                                         asset->width, 
1044                                         asset->height, 
1045                                         asset->width,                   /* Dimensions of output_rows */
1046                                         asset->height, 
1047                                         frame->get_color_model(),             /* One of the color model #defines */
1048                                         file->current_layer);
1049                         break;
1051 // Use Temp
1052                 default:
1053 // Read these directly
1054                         if(frame->get_color_model() == src_cmodel)
1055                         {
1056                                 mpeg3_read_yuvframe(fd,
1057                                         (char*)frame->get_y(),
1058                                         (char*)frame->get_u(),
1059                                         (char*)frame->get_v(),
1060                                         0,
1061                                         0,
1062                                         asset->width,
1063                                         asset->height,
1064                                         file->current_layer);
1066                         }
1067                         else
1068 // Process through temp frame
1069                         {
1070                                 char *y, *u, *v;
1071                                 mpeg3_read_yuvframe_ptr(fd,
1072                                         &y,
1073                                         &u,
1074                                         &v,
1075                                         file->current_layer);
1076                                 if(y && u && v)
1077                                 {
1078                                         cmodel_transfer(frame->get_rows(), 
1079                                                 0,
1080                                                 frame->get_y(),
1081                                                 frame->get_u(),
1082                                                 frame->get_v(),
1083                                                 (unsigned char*)y,
1084                                                 (unsigned char*)u,
1085                                                 (unsigned char*)v,
1086                                                 0,
1087                                                 0,
1088                                                 asset->width,
1089                                                 asset->height,
1090                                                 0,
1091                                                 0,
1092                                                 asset->width,
1093                                                 asset->height,
1094                                                 src_cmodel, 
1095                                                 frame->get_color_model(),
1096                                                 0, 
1097                                                 asset->width,
1098                                                 frame->get_w());
1099                                 }
1100                         }
1101 SET_TRACE
1102                         break;
1103         }
1105         return result;
1108 void FileMPEG::to_streamchannel(int channel, int &stream_out, int &channel_out)
1110         for(stream_out = 0, channel_out = file->current_channel; 
1111                 stream_out < mpeg3_total_astreams(fd) && 
1112                         channel_out >= mpeg3_audio_channels(fd, stream_out);
1113                 channel_out -= mpeg3_audio_channels(fd, stream_out), stream_out++)
1114         ;
1117 int FileMPEG::read_samples(double *buffer, int64_t len)
1119         if(!fd) return 0;
1121 // This is directed to a FileMPEGBuffer
1122         float *temp_float = new float[len];
1123 // Translate pure channel to a stream and a channel in the mpeg stream
1124         int stream, channel;
1125         to_streamchannel(file->current_channel, stream, channel);
1126         
1127         
1128         
1129 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
1131         mpeg3_set_sample(fd, 
1132                 file->current_sample,
1133                 stream);
1134         mpeg3_read_audio(fd, 
1135                 temp_float,      /* Pointer to pre-allocated buffer of floats */
1136                 0,      /* Pointer to pre-allocated buffer of int16's */
1137                 channel,          /* Channel to decode */
1138                 len,         /* Number of samples to decode */
1139                 stream);          /* Stream containing the channel */
1142 //      last_sample = file->current_sample;
1143         for(int i = 0; i < len; i++) buffer[i] = temp_float[i];
1145         delete [] temp_float;
1146         return 0;
1149 int FileMPEG::prefer_samples_float()
1151         return 1;
1154 int FileMPEG::read_samples_float(float *buffer, int64_t len)
1156         if(!fd) return 0;
1158 // Translate pure channel to a stream and a channel in the mpeg stream
1159         int stream, channel;
1160         to_streamchannel(file->current_channel, stream, channel);
1161         
1162         
1163 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
1165         mpeg3_set_sample(fd, 
1166                 file->current_sample,
1167                 stream);
1168         mpeg3_read_audio(fd, 
1169                 buffer,         /* Pointer to pre-allocated buffer of floats */
1170                 0,              /* Pointer to pre-allocated buffer of int16's */
1171                 channel,          /* Channel to decode */
1172                 len,         /* Number of samples to decode */
1173                 stream);          /* Stream containing the channel */
1176 //      last_sample = file->current_sample;
1178 //printf("FileMPEG::read_samples 100\n");
1179         return 0;
1184 char* FileMPEG::strtocompression(char *string)
1186         return "";
1189 char* FileMPEG::compressiontostr(char *string)
1191         return "";
1200 FileMPEGVideo::FileMPEGVideo(FileMPEG *file)
1201  : Thread(1, 0, 0)
1203         this->file = file;
1204         
1205         
1206         if(file->asset->vmpeg_cmodel == MPEG_YUV422)
1207         {
1208                 mpeg2enc_init_buffers();
1209                 mpeg2enc_set_w(file->asset->width);
1210                 mpeg2enc_set_h(file->asset->height);
1211                 mpeg2enc_set_rate(file->asset->frame_rate);
1212         }
1215 FileMPEGVideo::~FileMPEGVideo()
1217         Thread::join();
1220 void FileMPEGVideo::run()
1222         if(file->asset->vmpeg_cmodel == MPEG_YUV422)
1223         {
1224                 printf("FileMPEGVideo::run ");
1225                 for(int i = 0; i < file->vcommand_line.total; i++)
1226                 printf("%s ", file->vcommand_line.values[i]);
1227                 printf("\n");
1228                 mpeg2enc(file->vcommand_line.total, file->vcommand_line.values);
1229         }
1230         else
1231         {
1232                 while(1)
1233                 {
1234                         file->next_frame_lock->lock("FileMPEGVideo::run");
1235                         if(file->mjpeg_eof) 
1236                         {
1237                                 file->next_frame_done->unlock();
1238                                 break;
1239                         }
1243 // YUV4 sequence header
1244                         if(!file->wrote_header)
1245                         {
1246                                 file->wrote_header = 1;
1248                                 char string[BCTEXTLEN];
1249                                 char interlace_string[BCTEXTLEN];
1250                                 if(!file->asset->vmpeg_progressive)
1251                                 {
1252                                         sprintf(interlace_string, file->asset->vmpeg_field_order ? "b" : "t");
1253                                 }
1254                                 else
1255                                 {
1256                                         sprintf(interlace_string, "p");
1257                                 }
1259                                 fprintf(file->mjpeg_out, "YUV4MPEG2 W%d H%d F%d:%d I%s A%d:%d C%s\n",
1260                                         file->asset->width,
1261                                         file->asset->height,
1262                                         (int)(file->asset->frame_rate * 1001),
1263                                         1001,
1264                                         interlace_string,
1265                                         (int)(file->asset->aspect_ratio * 1000),
1266                                         1000,
1267                                         "420mpeg2");
1268                         }
1270 // YUV4 frame header
1271                         fprintf(file->mjpeg_out, "FRAME\n");
1273 // YUV data
1274                         if(!fwrite(file->mjpeg_y, file->asset->width * file->asset->height, 1, file->mjpeg_out))
1275                                 file->mjpeg_error = 1;
1276                         if(!fwrite(file->mjpeg_u, file->asset->width * file->asset->height / 4, 1, file->mjpeg_out))
1277                                 file->mjpeg_error = 1;
1278                         if(!fwrite(file->mjpeg_v, file->asset->width * file->asset->height / 4, 1, file->mjpeg_out))
1279                                 file->mjpeg_error = 1;
1280                         fflush(file->mjpeg_out);
1282                         file->next_frame_done->unlock();
1283                 }
1284                 pclose(file->mjpeg_out);
1285                 file->mjpeg_out = 0;
1286         }
1308 FileMPEGAudio::FileMPEGAudio(FileMPEG *file)
1309  : Thread(1, 0, 0)
1311         this->file = file;
1312         toolame_init_buffers();
1315 FileMPEGAudio::~FileMPEGAudio()
1317         Thread::join();
1320 void FileMPEGAudio::run()
1322         file->toolame_result = toolame(file->acommand_line.total, file->acommand_line.values);
1332 MPEGConfigAudio::MPEGConfigAudio(BC_WindowBase *parent_window, Asset *asset)
1333  : BC_Window(PROGRAM_NAME ": Audio Compression",
1334         parent_window->get_abs_cursor_x(1),
1335         parent_window->get_abs_cursor_y(1),
1336         310,
1337         120,
1338         -1,
1339         -1,
1340         0,
1341         0,
1342         1)
1344         this->parent_window = parent_window;
1345         this->asset = asset;
1348 MPEGConfigAudio::~MPEGConfigAudio()
1352 int MPEGConfigAudio::create_objects()
1354         int x = 10, y = 10;
1355         int x1 = 150;
1356         MPEGLayer *layer;
1358         add_tool(new BC_Title(x, y, _("Layer:")));
1359         add_tool(layer = new MPEGLayer(x1, y, this));
1360         layer->create_objects();
1362         y += 30;
1363         add_tool(new BC_Title(x, y, _("Kbits per second:")));
1364         add_tool(bitrate = new MPEGABitrate(x1, y, this));
1365         bitrate->create_objects();
1366         
1367         
1368         add_subwindow(new BC_OKButton(this));
1369         show_window();
1370         flush();
1371         return 0;
1374 int MPEGConfigAudio::close_event()
1376         set_done(0);
1377         return 1;
1386 MPEGLayer::MPEGLayer(int x, int y, MPEGConfigAudio *gui)
1387  : BC_PopupMenu(x, y, 100, layer_to_string(gui->asset->ampeg_derivative))
1389         this->gui = gui;
1392 void MPEGLayer::create_objects()
1394         add_item(new BC_MenuItem(layer_to_string(2)));
1395         add_item(new BC_MenuItem(layer_to_string(3)));
1398 int MPEGLayer::handle_event()
1400         gui->asset->ampeg_derivative = string_to_layer(get_text());
1401         gui->bitrate->set_layer(gui->asset->ampeg_derivative);
1402         return 1;
1405 int MPEGLayer::string_to_layer(char *string)
1407         if(!strcasecmp(layer_to_string(2), string))
1408                 return 2;
1409         if(!strcasecmp(layer_to_string(3), string))
1410                 return 3;
1412         return 2;
1415 char* MPEGLayer::layer_to_string(int layer)
1417         switch(layer)
1418         {
1419                 case 2:
1420                         return _("II");
1421                         break;
1422                 
1423                 case 3:
1424                         return _("III");
1425                         break;
1426                         
1427                 default:
1428                         return _("II");
1429                         break;
1430         }
1439 MPEGABitrate::MPEGABitrate(int x, int y, MPEGConfigAudio *gui)
1440  : BC_PopupMenu(x, 
1441         y, 
1442         100, 
1443         bitrate_to_string(gui->string, gui->asset->ampeg_bitrate))
1445         this->gui = gui;
1448 void MPEGABitrate::create_objects()
1450         set_layer(gui->asset->ampeg_derivative);
1453 void MPEGABitrate::set_layer(int layer)
1455         while(total_items())
1456         {
1457                 remove_item(0);
1458         }
1460         if(layer == 2)
1461         {
1462                 add_item(new BC_MenuItem("160"));
1463                 add_item(new BC_MenuItem("192"));
1464                 add_item(new BC_MenuItem("224"));
1465                 add_item(new BC_MenuItem("256"));
1466                 add_item(new BC_MenuItem("320"));
1467                 add_item(new BC_MenuItem("384"));
1468         }
1469         else
1470         {
1471                 add_item(new BC_MenuItem("8"));
1472                 add_item(new BC_MenuItem("16"));
1473                 add_item(new BC_MenuItem("24"));
1474                 add_item(new BC_MenuItem("32"));
1475                 add_item(new BC_MenuItem("40"));
1476                 add_item(new BC_MenuItem("48"));
1477                 add_item(new BC_MenuItem("56"));
1478                 add_item(new BC_MenuItem("64"));
1479                 add_item(new BC_MenuItem("80"));
1480                 add_item(new BC_MenuItem("96"));
1481                 add_item(new BC_MenuItem("112"));
1482                 add_item(new BC_MenuItem("128"));
1483                 add_item(new BC_MenuItem("144"));
1484                 add_item(new BC_MenuItem("160"));
1485                 add_item(new BC_MenuItem("192"));
1486                 add_item(new BC_MenuItem("224"));
1487                 add_item(new BC_MenuItem("256"));
1488                 add_item(new BC_MenuItem("320"));
1489         }
1492 int MPEGABitrate::handle_event()
1494         gui->asset->ampeg_bitrate = string_to_bitrate(get_text());
1495         return 1;
1498 int MPEGABitrate::string_to_bitrate(char *string)
1500         return atol(string);
1504 char* MPEGABitrate::bitrate_to_string(char *string, int bitrate)
1506         sprintf(string, "%d", bitrate);
1507         return string;
1518 MPEGConfigVideo::MPEGConfigVideo(BC_WindowBase *parent_window, 
1519         Asset *asset)
1520  : BC_Window(PROGRAM_NAME ": Video Compression",
1521         parent_window->get_abs_cursor_x(1),
1522         parent_window->get_abs_cursor_y(1),
1523         500,
1524         400,
1525         -1,
1526         -1,
1527         0,
1528         0,
1529         1)
1531         this->parent_window = parent_window;
1532         this->asset = asset;
1533         reset_cmodel();
1536 MPEGConfigVideo::~MPEGConfigVideo()
1540 int MPEGConfigVideo::create_objects()
1542         int x = 10, y = 10;
1543         int x1 = x + 150;
1544         int x2 = x + 300;
1547         add_subwindow(new BC_Title(x, y, _("Color model:")));
1548         add_subwindow(cmodel = new MPEGColorModel(x1, y, this));
1549         cmodel->create_objects();
1550         y += 30;
1552         update_cmodel_objs();
1554         add_subwindow(new BC_OKButton(this));
1555         show_window();
1556         flush();
1557         return 0;
1560 int MPEGConfigVideo::close_event()
1562         set_done(0);
1563         return 1;
1567 void MPEGConfigVideo::delete_cmodel_objs()
1569         delete preset;
1570         delete derivative;
1571         delete bitrate;
1572         delete fixed_bitrate;
1573         delete quant;
1574         delete fixed_quant;
1575         delete iframe_distance;
1576         delete pframe_distance;
1577         delete top_field_first;
1578         delete progressive;
1579         delete denoise;
1580         delete seq_codes;
1581         titles.remove_all_objects();
1582         reset_cmodel();
1585 void MPEGConfigVideo::reset_cmodel()
1587         preset = 0;
1588         derivative = 0;
1589         bitrate = 0;
1590         fixed_bitrate = 0;
1591         quant = 0;
1592         fixed_quant = 0;
1593         iframe_distance = 0;
1594         pframe_distance = 0;
1595         top_field_first = 0;
1596         progressive = 0;
1597         denoise = 0;
1598         seq_codes = 0;
1601 void MPEGConfigVideo::update_cmodel_objs()
1603         BC_Title *title;
1604         int x = 10;
1605         int y = 40;
1606         int x1 = x + 150;
1607         int x2 = x + 280;
1609         delete_cmodel_objs();
1611         if(asset->vmpeg_cmodel == MPEG_YUV420)
1612         {
1613                 add_subwindow(title = new BC_Title(x, y + 5, _("Format Preset:")));
1614                 titles.append(title);
1615                 add_subwindow(preset = new MPEGPreset(x1, y, this));
1616                 preset->create_objects();
1617                 y += 30;
1618         }
1620         add_subwindow(title = new BC_Title(x, y + 5, _("Derivative:")));
1621         titles.append(title);
1622         add_subwindow(derivative = new MPEGDerivative(x1, y, this));
1623         derivative->create_objects();
1624         y += 30;
1626         add_subwindow(title = new BC_Title(x, y + 5, _("Bitrate:")));
1627         titles.append(title);
1628         add_subwindow(bitrate = new MPEGBitrate(x1, y, this));
1629         add_subwindow(fixed_bitrate = new MPEGFixedBitrate(x2, y, this));
1630         y += 30;
1632         add_subwindow(title = new BC_Title(x, y, _("Quantization:")));
1633         titles.append(title);
1634         quant = new MPEGQuant(x1, y, this);
1635         quant->create_objects();
1636         add_subwindow(fixed_quant = new MPEGFixedQuant(x2, y, this));
1637         y += 30;
1639         add_subwindow(title = new BC_Title(x, y, _("I frame distance:")));
1640         titles.append(title);
1641         iframe_distance = new MPEGIFrameDistance(x1, y, this);
1642         iframe_distance->create_objects();
1643         y += 30;
1645         if(asset->vmpeg_cmodel == MPEG_YUV420)
1646         {
1647                 add_subwindow(title = new BC_Title(x, y, _("P frame distance:")));
1648                 titles.append(title);
1649                 pframe_distance = new MPEGPFrameDistance(x1, y, this);
1650                 pframe_distance->create_objects();
1651                 y += 30;
1653                 add_subwindow(top_field_first = new BC_CheckBox(x, y, &asset->vmpeg_field_order, _("Bottom field first")));
1654                 y += 30;
1655         }
1657         add_subwindow(progressive = new BC_CheckBox(x, y, &asset->vmpeg_progressive, _("Progressive frames")));
1658         y += 30;
1659         add_subwindow(denoise = new BC_CheckBox(x, y, &asset->vmpeg_denoise, _("Denoise")));
1660         y += 30;
1661         add_subwindow(seq_codes = new BC_CheckBox(x, y, &asset->vmpeg_seq_codes, _("Sequence start codes in every GOP")));
1677 MPEGDerivative::MPEGDerivative(int x, int y, MPEGConfigVideo *gui)
1678  : BC_PopupMenu(x, y, 150, derivative_to_string(gui->asset->vmpeg_derivative))
1680         this->gui = gui;
1683 void MPEGDerivative::create_objects()
1685         add_item(new BC_MenuItem(derivative_to_string(1)));
1686         add_item(new BC_MenuItem(derivative_to_string(2)));
1689 int MPEGDerivative::handle_event()
1691         gui->asset->vmpeg_derivative = string_to_derivative(get_text());
1692         return 1;
1695 int MPEGDerivative::string_to_derivative(char *string)
1697         if(!strcasecmp(derivative_to_string(1), string))
1698                 return 1;
1699         if(!strcasecmp(derivative_to_string(2), string))
1700                 return 2;
1702         return 1;
1705 char* MPEGDerivative::derivative_to_string(int derivative)
1707         switch(derivative)
1708         {
1709                 case 1:
1710                         return _("MPEG-1");
1711                         break;
1712                 
1713                 case 2:
1714                         return _("MPEG-2");
1715                         break;
1716                         
1717                 default:
1718                         return _("MPEG-1");
1719                         break;
1720         }
1733 MPEGPreset::MPEGPreset(int x, int y, MPEGConfigVideo *gui)
1734  : BC_PopupMenu(x, y, 200, value_to_string(gui->asset->vmpeg_preset))
1736         this->gui = gui;
1739 void MPEGPreset::create_objects()
1741         for(int i = 0; i < 10; i++)
1742         {
1743                 add_item(new BC_MenuItem(value_to_string(i)));
1744         }
1747 int MPEGPreset::handle_event()
1749         gui->asset->vmpeg_preset = string_to_value(get_text());
1750         return 1;
1753 int MPEGPreset::string_to_value(char *string)
1755         for(int i = 0; i < 10; i++)
1756         {
1757                 if(!strcasecmp(value_to_string(i), string))
1758                         return i;
1759         }
1760         return 0;
1763 char* MPEGPreset::value_to_string(int derivative)
1765         switch(derivative)
1766         {
1767                 case 0: return _("Generic MPEG-1"); break;
1768                 case 1: return _("standard VCD"); break;
1769                 case 2: return _("user VCD"); break;
1770                 case 3: return _("Generic MPEG-2"); break;
1771                 case 4: return _("standard SVCD"); break;
1772                 case 5: return _("user SVCD"); break;
1773                 case 6: return _("VCD Still sequence"); break;
1774                 case 7: return _("SVCD Still sequence"); break;
1775                 case 8: return _("DVD NAV"); break;
1776                 case 9: return _("DVD"); break;
1777                 default: return _("Generic MPEG-1"); break;
1778         }
1791 MPEGBitrate::MPEGBitrate(int x, int y, MPEGConfigVideo *gui)
1792  : BC_TextBox(x, y, 100, 1, gui->asset->vmpeg_bitrate)
1794         this->gui = gui;
1798 int MPEGBitrate::handle_event()
1800         gui->asset->vmpeg_bitrate = atol(get_text());
1801         return 1;
1808 MPEGQuant::MPEGQuant(int x, int y, MPEGConfigVideo *gui)
1809  : BC_TumbleTextBox(gui, 
1810         (int64_t)gui->asset->vmpeg_quantization, 
1811         (int64_t)1,
1812         (int64_t)100,
1813         x, 
1814         y,
1815         100)
1817         this->gui = gui;
1820 int MPEGQuant::handle_event()
1822         gui->asset->vmpeg_quantization = atol(get_text());
1823         return 1;
1826 MPEGFixedBitrate::MPEGFixedBitrate(int x, int y, MPEGConfigVideo *gui)
1827  : BC_Radial(x, y, gui->asset->vmpeg_fix_bitrate, _("Fixed bitrate"))
1829         this->gui = gui;
1832 int MPEGFixedBitrate::handle_event()
1834         update(1);
1835         gui->asset->vmpeg_fix_bitrate = 1;
1836         gui->fixed_quant->update(0);
1837         return 1;
1840 MPEGFixedQuant::MPEGFixedQuant(int x, int y, MPEGConfigVideo *gui)
1841  : BC_Radial(x, y, !gui->asset->vmpeg_fix_bitrate, _("Fixed quantization"))
1843         this->gui = gui;
1846 int MPEGFixedQuant::handle_event()
1848         update(1);
1849         gui->asset->vmpeg_fix_bitrate = 0;
1850         gui->fixed_bitrate->update(0);
1851         return 1;
1862 MPEGIFrameDistance::MPEGIFrameDistance(int x, int y, MPEGConfigVideo *gui)
1863  : BC_TumbleTextBox(gui, 
1864         (int64_t)gui->asset->vmpeg_iframe_distance, 
1865         (int64_t)1,
1866         (int64_t)100,
1867         x, 
1868         y,
1869         50)
1871         this->gui = gui;
1874 int MPEGIFrameDistance::handle_event()
1876         gui->asset->vmpeg_iframe_distance = atoi(get_text());
1877         return 1;
1886 MPEGPFrameDistance::MPEGPFrameDistance(int x, int y, MPEGConfigVideo *gui)
1887  : BC_TumbleTextBox(gui, 
1888         (int64_t)gui->asset->vmpeg_pframe_distance, 
1889         (int64_t)0,
1890         (int64_t)2,
1891         x, 
1892         y,
1893         50)
1895         this->gui = gui;
1898 int MPEGPFrameDistance::handle_event()
1900         gui->asset->vmpeg_pframe_distance = atoi(get_text());
1901         return 1;
1911 MPEGColorModel::MPEGColorModel(int x, int y, MPEGConfigVideo *gui)
1912  : BC_PopupMenu(x, y, 150, cmodel_to_string(gui->asset->vmpeg_cmodel))
1914         this->gui = gui;
1917 void MPEGColorModel::create_objects()
1919         add_item(new BC_MenuItem(cmodel_to_string(0)));
1920         add_item(new BC_MenuItem(cmodel_to_string(1)));
1923 int MPEGColorModel::handle_event()
1925         gui->asset->vmpeg_cmodel = string_to_cmodel(get_text());
1926         gui->update_cmodel_objs();
1927         return 1;
1930 int MPEGColorModel::string_to_cmodel(char *string)
1932         if(!strcasecmp(cmodel_to_string(0), string))
1933                 return 0;
1934         if(!strcasecmp(cmodel_to_string(1), string))
1935                 return 1;
1936         return 1;
1939 char* MPEGColorModel::cmodel_to_string(int cmodel)
1941         switch(cmodel)
1942         {
1943                 case MPEG_YUV420:
1944                         return _("YUV 4:2:0");
1945                         break;
1946                 
1947                 case MPEG_YUV422:
1948                         return _("YUV 4:2:2");
1949                         break;
1950                         
1951                 default:
1952                         return _("YUV 4:2:0");
1953                         break;
1954         }