r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / filempeg.C
blobf025bcd10de455af023c57a174b71e17b06df74f
1 #include "assets.h"
2 #include "bitspopup.h"
3 #include "byteorder.h"
4 #include "clip.h"
5 #include "file.h"
6 #include "edit.h"
7 #include "filempeg.h"
8 #include "guicast.h"
9 #include "mwindow.inc"
10 #include "vframe.h"
11 #include "videodevice.inc"
13 #include <stdio.h>
14 #include <string.h>
15 #include <unistd.h>
16 #include <libintl.h>
17 #define _(String) gettext(String)
18 #define gettext_noop(String) String
19 #define N_(String) gettext_noop (String)
22 FileMPEG::FileMPEG(Asset *asset, File *file)
23  : FileBase(asset, file)
25         reset_parameters();
26 // May also be VMPEG or AMPEG if write status.
27         if(asset->format == FILE_UNKNOWN) asset->format = FILE_MPEG;
28         asset->byte_order = 0;
31 FileMPEG::~FileMPEG()
33         close_file();
36 void FileMPEG::get_parameters(BC_WindowBase *parent_window, 
37         Asset *asset, 
38         BC_WindowBase* &format_window,
39         int audio_options,
40         int video_options)
42         if(audio_options && asset->format == FILE_AMPEG)
43         {
44                 MPEGConfigAudio *window = new MPEGConfigAudio(parent_window, asset);
45                 format_window = window;
46                 window->create_objects();
47                 window->run_window();
48                 delete window;
49         }
50         else
51         if(video_options && asset->format == FILE_VMPEG)
52         {
53                 MPEGConfigVideo *window = new MPEGConfigVideo(parent_window, asset);
54                 format_window = window;
55                 window->create_objects();
56                 window->run_window();
57                 delete window;
58         }
61 int FileMPEG::check_sig(Asset *asset)
63         return mpeg3_check_sig(asset->path);
66 int FileMPEG::reset_parameters_derived()
68         fd = 0;
69         video_out = 0;
70         audio_out = 0;
71         prev_track = 0;
72         temp_frame = 0;
73         toolame_temp = 0;
74         toolame_allocation = 0;
75         toolame_result = 0;
76         lame_temp[0] = 0;
77         lame_temp[1] = 0;
78         lame_allocation = 0;
79         lame_global = 0;
80         lame_output = 0;
81         lame_output_allocation = 0;
82         lame_fd = 0;
83         lame_started = 0;
87 // Just create the Quicktime objects since this routine is also called
88 // for reopening.
89 int FileMPEG::open_file(int rd, int wr)
91         int result = 0;
92         this->rd = rd;
93         this->wr = wr;
94 //printf("FileMPEG::open_file: 1 %d %d %d\n", rd, wr, asset->format);
96         if(rd)
97         {
98                 if(!(fd = mpeg3_open(asset->path)))
99                 {
100                         printf("FileMPEG::open_file %s\n", asset->path);
101                         result = 1;
102                 }
103                 else
104                 {
105                         mpeg3_set_cpus(fd, file->cpus);
106                         mpeg3_set_mmx(fd, 0);
108                         asset->audio_data = mpeg3_has_audio(fd);
109                         if(asset->audio_data)
110                         {
111                                 asset->channels = 0;
112                                 for(int i = 0; i < mpeg3_total_astreams(fd); i++)
113                                 {
114                                         asset->channels += mpeg3_audio_channels(fd, i);
115                                 }
116                                 if(!asset->sample_rate)
117                                         asset->sample_rate = mpeg3_sample_rate(fd, 0);
118                                 asset->audio_length = mpeg3_audio_samples(fd, 0); 
119         //printf("FileMPEG::open_file 1 %d\n", asset->audio_length);
120                         }
122                         asset->video_data = mpeg3_has_video(fd);
123                         if(asset->video_data)
124                         {
125                                 asset->layers = mpeg3_total_vstreams(fd);
126                                 asset->width = mpeg3_video_width(fd, 0);
127                                 asset->height = mpeg3_video_height(fd, 0);
128                                 asset->video_length = mpeg3_video_frames(fd, 0);
129                                 asset->vmpeg_cmodel = (mpeg3_colormodel(fd, 0) == MPEG3_YUV422P) ? 1 : 0;
130                                 if(!asset->frame_rate)
131                                         asset->frame_rate = mpeg3_frame_rate(fd, 0);
132 //printf("FileMPEG::open_file 2 %d\n", asset->video_length);
133                         }
134                 }
135         }
136         
137 //printf("FileMPEG::open_file 2 %d\n", asset->video_length);
138         
139         
140         if(wr && asset->format == FILE_VMPEG)
141         {
142                 char bitrate_string[BCTEXTLEN];
143                 char quant_string[BCTEXTLEN];
144                 char iframe_string[BCTEXTLEN];
146                 sprintf(bitrate_string, "%d", asset->vmpeg_bitrate);
147                 sprintf(quant_string, "%d", asset->vmpeg_quantization);
148                 sprintf(iframe_string, "%d", asset->vmpeg_iframe_distance);
150 // Construct command line
151                 if(!result)
152                 {
153                         append_vcommand_line("mpeg2enc");
154                         append_vcommand_line(asset->vmpeg_derivative == 1 ? "-1" : "");
155                         append_vcommand_line(asset->vmpeg_cmodel == 1 ? "-422" : "");
156                         if(asset->vmpeg_fix_bitrate)
157                         {
158                                 append_vcommand_line("-b");
159                                 append_vcommand_line(bitrate_string);
160                         }
161                         else
162                         {
163                                 append_vcommand_line("-q");
164                                 append_vcommand_line(quant_string);
165                         }
166                         append_vcommand_line(!asset->vmpeg_fix_bitrate ? quant_string : "");
167                         append_vcommand_line("-n");
168                         append_vcommand_line(iframe_string);
169                         append_vcommand_line(asset->vmpeg_progressive ? "-p" : "");
170                         append_vcommand_line(asset->vmpeg_denoise ? "-d" : "");
171                         append_vcommand_line(file->cpus <= 1 ? "-u" : "");
172                         append_vcommand_line(asset->vmpeg_seq_codes ? "-g" : "");
173                         append_vcommand_line(asset->path);
175                         video_out = new FileMPEGVideo(this);
176                         video_out->start();
177                 }
178         }
180         if(wr && asset->format == FILE_AMPEG)
181         {
182                 char command_line[BCTEXTLEN];
183                 char encoder_string[BCTEXTLEN];
184                 char argument_string[BCTEXTLEN];
186 //printf("FileMPEG::open_file 1 %d\n", asset->ampeg_derivative);
187                 encoder_string[0] = 0;
189                 if(asset->ampeg_derivative == 2)
190                 {
191                         char string[BCTEXTLEN];
192                         append_acommand_line("toolame");
193                         append_acommand_line("-m");
194                         append_acommand_line((asset->channels >= 2) ? "j" : "m");
195                         sprintf(string, "%f", (float)asset->sample_rate / 1000);
196                         append_acommand_line("-s");
197                         append_acommand_line(string);
198                         sprintf(string, "%d", asset->ampeg_bitrate);
199                         append_acommand_line("-b");
200                         append_acommand_line(string);
201                         append_acommand_line("-");
202                         append_acommand_line(asset->path);
204                         audio_out = new FileMPEGAudio(this);
205                         audio_out->start();
206                 }
207                 else
208                 if(asset->ampeg_derivative == 3)
209                 {
210                         lame_global = lame_init();
211                         lame_set_brate(lame_global, asset->ampeg_bitrate / 1000);
212                         lame_set_quality(lame_global, 0);
213                         lame_set_in_samplerate(lame_global, 
214                                 asset->sample_rate);
215                         if((result = lame_init_params(lame_global)) < 0)
216                         {
217                                 printf(_("encode: lame_init_params returned %d\n"), result);
218                                 lame_close(lame_global);
219                                 lame_global = 0;
220                         }
221                         else
222                         if(!(lame_fd = fopen(asset->path, "w")))
223                         {
224                                 perror("FileMPEG::open_file");
225                                 lame_close(lame_global);
226                                 lame_global = 0;
227                         }
228                 }
229                 else
230                 {
231                         printf("FileMPEG::open_file: ampeg_derivative=%d\n", asset->ampeg_derivative);
232                         result = 1;
233                 }
234         }
236 //asset->dump();
237 //printf("FileMPEG::open_file 100\n");
238         return result;
241 void FileMPEG::append_vcommand_line(const char *string)
243         if(string[0])
244         {
245                 char *argv = strdup(string);
246                 vcommand_line.append(argv);
247         }
250 void FileMPEG::append_acommand_line(const char *string)
252         if(string[0])
253         {
254                 char *argv = strdup(string);
255                 acommand_line.append(argv);
256         }
260 int FileMPEG::close_file()
262 //printf("FileMPEG::close_file 1\n");
263         if(fd)
264         {
265                 mpeg3_close(fd);
266         }
268         if(video_out)
269         {
270 // End of sequence signal
271                 mpeg2enc_set_input_buffers(1, 0, 0, 0);
272                 delete video_out;
273                 video_out = 0;
274         }
276         vcommand_line.remove_all_objects();
277         acommand_line.remove_all_objects();
279         if(audio_out)
280         {
281                 toolame_send_buffer(0, 0);
282                 delete audio_out;
283                 audio_out = 0;
284         }
286         if(lame_global)
287                 lame_close(lame_global);
289         if(temp_frame) delete temp_frame;
290         if(toolame_temp) delete [] toolame_temp;
292         if(lame_temp[0]) delete [] lame_temp[0];
293         if(lame_temp[1]) delete [] lame_temp[1];
294         if(lame_output) delete [] lame_output;
295         if(lame_fd) fclose(lame_fd);
297         reset_parameters();
298         FileBase::close_file();
299 //printf("FileMPEG::close_file 100\n");
300         return 0;
303 int FileMPEG::get_best_colormodel(Asset *asset, int driver)
305 //printf("FileMPEG::get_best_colormodel 1\n");
306         switch(driver)
307         {
308                 case PLAYBACK_X11:
309                         return BC_RGB888;
310                         if(asset->vmpeg_cmodel == 0) return BC_YUV420P;
311                         if(asset->vmpeg_cmodel == 1) return BC_YUV422P;
312                         break;
313                 case PLAYBACK_X11_XV:
314                         if(asset->vmpeg_cmodel == 0) return BC_YUV420P;
315                         if(asset->vmpeg_cmodel == 1) return BC_YUV422P;
316                         break;
317                 case PLAYBACK_LML:
318                 case PLAYBACK_BUZ:
319                         return BC_YUV422P;
320                         break;
321                 case PLAYBACK_FIREWIRE:
322                         return BC_YUV422P;
323                         break;
324                 case VIDEO4LINUX:
325                 case VIDEO4LINUX2:
326                         if(asset->vmpeg_cmodel == 0) return BC_YUV420P;
327                         if(asset->vmpeg_cmodel == 1) return BC_YUV422P;
328                         break;
329                 case CAPTURE_BUZ:
330                 case CAPTURE_LML:
331                         return BC_YUV422;
332                         break;
333                 case CAPTURE_FIREWIRE:
334                         return BC_YUV422P;
335                         break;
336         }
337 //printf("FileMPEG::get_best_colormodel 100\n");
340 int FileMPEG::colormodel_supported(int colormodel)
342         return colormodel;
346 int FileMPEG::can_copy_from(Edit *edit, int64_t position)
348         if(!fd) return 0;
349         return 0;
352 int FileMPEG::set_audio_position(int64_t sample)
354 #if 0
355         if(!fd) return 1;
356         
357         int channel, stream;
358         to_streamchannel(file->current_channel, stream, channel);
360 //printf("FileMPEG::set_audio_position %d %d %d\n", sample, mpeg3_get_sample(fd, stream), last_sample);
361         if(sample != mpeg3_get_sample(fd, stream) &&
362                 sample != last_sample)
363         {
364                 if(sample >= 0 && sample < asset->audio_length)
365                 {
366 //printf("FileMPEG::set_audio_position seeking stream %d\n", sample);
367                         return mpeg3_set_sample(fd, sample, stream);
368                 }
369                 else
370                         return 1;
371         }
372 #endif
373         return 0;
376 int FileMPEG::set_video_position(int64_t x)
378         if(!fd) return 1;
379         if(x >= 0 && x < asset->video_length)
380                 return mpeg3_set_frame(fd, x, file->current_layer);
381         else
382                 return 1;
386 int FileMPEG::write_samples(double **buffer, int64_t len)
388         int result = 0;
390 //printf("FileMPEG::write_samples 1\n");
391         if(asset->ampeg_derivative == 2)
392         {
393 // Convert to int16
394                 int channels = MIN(asset->channels, 2);
395                 int64_t audio_size = len * channels * 2;
396                 if(toolame_allocation < audio_size)
397                 {
398                         if(toolame_temp) delete [] toolame_temp;
399                         toolame_temp = new unsigned char[audio_size];
400                         toolame_allocation = audio_size;
401                 }
403                 for(int i = 0; i < channels; i++)
404                 {
405                         int16_t *output = ((int16_t*)toolame_temp) + i;
406                         double *input = buffer[i];
407                         for(int j = 0; j < len; j++)
408                         {
409                                 int sample = (int)(*input * 0x7fff);
410                                 *output = (int16_t)(CLIP(sample, -0x8000, 0x7fff));
411                                 output += channels;
412                                 input++;
413                         }
414                 }
415                 result = toolame_send_buffer((char*)toolame_temp, audio_size);
416         }
417         else
418         if(asset->ampeg_derivative == 3)
419         {
420                 int channels = MIN(asset->channels, 2);
421                 int64_t audio_size = len * channels;
422                 if(!lame_global) return 1;
423                 if(!lame_fd) return 1;
424                 if(lame_allocation < audio_size)
425                 {
426                         if(lame_temp[0]) delete [] lame_temp[0];
427                         if(lame_temp[1]) delete [] lame_temp[1];
428                         lame_temp[0] = new float[audio_size];
429                         lame_temp[1] = new float[audio_size];
430                         lame_allocation = audio_size;
431                 }
433                 if(lame_output_allocation < audio_size * 4)
434                 {
435                         if(lame_output) delete [] lame_output;
436                         lame_output_allocation = audio_size * 4;
437                         lame_output = new char[lame_output_allocation];
438                 }
440                 for(int i = 0; i < channels; i++)
441                 {
442                         float *output = lame_temp[i];
443                         double *input = buffer[i];
444                         for(int j = 0; j < len; j++)
445                         {
446                                 *output++ = *input++ * (float)32768;
447                         }
448                 }
450                 result = lame_encode_buffer_float(lame_global,
451                         lame_temp[0],
452                         (channels > 1) ? lame_temp[1] : lame_temp[0],
453                         len,
454                         (unsigned char*)lame_output,
455                         lame_output_allocation);
456                 if(result > 0)
457                 {
458                         char *real_output = lame_output;
459                         int bytes = result;
460                         if(!lame_started)
461                         {
462                                 for(int i = 0; i < bytes; i++)
463                                         if(lame_output[i])
464                                         {
465                                                 real_output = &lame_output[i];
466                                                 lame_started = 1;
467                                                 bytes -= i;
468                                                 break;
469                                         }
470                         }
471                         if(bytes > 0 && lame_started)
472                         {
473                                 result = !fwrite(real_output, 1, bytes, lame_fd);
474                                 if(result)
475                                         perror("FileMPEG::write_samples");
476                         }
477                         else
478                                 result = 0;
479                 }
480                 else
481                         result = 1;
482         }
484         return result;
487 int FileMPEG::write_frames(VFrame ***frames, int len)
489         int result = 0;
491         if(video_out)
492         {
493                 int temp_w = (int)((asset->width + 15) / 16) * 16;
494                 int temp_h;
495                 int output_cmodel = 
496                         (asset->vmpeg_cmodel == 0) ? BC_YUV420P : BC_YUV422P;
497                 
498                 
499 // Height depends on progressiveness
500                 if(asset->vmpeg_progressive || asset->vmpeg_derivative == 1)
501                         temp_h = (int)((asset->height + 15) / 16) * 16;
502                 else
503                         temp_h = (int)((asset->height + 31) / 32) * 32;
505 //printf("FileMPEG::write_frames 1\n");
506                 
507 // Only 1 layer is supported in MPEG output
508                 for(int i = 0; i < 1; i++)
509                 {
510                         for(int j = 0; j < len; j++)
511                         {
512                                 VFrame *frame = frames[i][j];
513                                 
514                                 
515                                 
516                                 if(frame->get_w() == temp_w &&
517                                         frame->get_h() == temp_h &&
518                                         frame->get_color_model() == output_cmodel)
519                                 {
520                                         mpeg2enc_set_input_buffers(0, 
521                                                 (char*)frame->get_y(),
522                                                 (char*)frame->get_u(),
523                                                 (char*)frame->get_v());
524                                 }
525                                 else
526                                 {
527 //printf("FileMPEG::write_frames 2\n");
528                                         if(temp_frame &&
529                                                 (temp_frame->get_w() != temp_w ||
530                                                 temp_frame->get_h() != temp_h ||
531                                                 temp_frame->get_color_model() || output_cmodel))
532                                         {
533                                                 delete temp_frame;
534                                                 temp_frame = 0;
535                                         }
536 //printf("FileMPEG::write_frames 3\n");
539                                         if(!temp_frame)
540                                         {
541                                                 temp_frame = new VFrame(0, 
542                                                         temp_w, 
543                                                         temp_h, 
544                                                         output_cmodel);
545                                         }
547                                         cmodel_transfer(temp_frame->get_rows(), 
548                                                 frame->get_rows(),
549                                                 temp_frame->get_y(),
550                                                 temp_frame->get_u(),
551                                                 temp_frame->get_v(),
552                                                 frame->get_y(),
553                                                 frame->get_u(),
554                                                 frame->get_v(),
555                                                 0,
556                                                 0,
557                                                 asset->width,
558                                                 asset->height,
559                                                 0,
560                                                 0,
561                                                 asset->width,
562                                                 asset->height,
563                                                 frame->get_color_model(), 
564                                                 temp_frame->get_color_model(),
565                                                 0, 
566                                                 frame->get_w(),
567                                                 temp_w);
569                                         mpeg2enc_set_input_buffers(0, 
570                                                 (char*)temp_frame->get_y(),
571                                                 (char*)temp_frame->get_u(),
572                                                 (char*)temp_frame->get_v());
573                                 }
574                         }
575                 }
576         }
578 //printf("FileMPEG::write_frames 100\n");
581         return result;
584 int FileMPEG::read_frame(VFrame *frame)
586         if(!fd) return 1;
587         int result = 0;
588         int src_cmodel;
590 //printf("FileMPEG::read_frame 1\n");
591         if(mpeg3_colormodel(fd, 0) == MPEG3_YUV420P)
592                 src_cmodel = BC_YUV420P;
593         else
594         if(mpeg3_colormodel(fd, 0) == MPEG3_YUV422P)
595                 src_cmodel = BC_YUV422P;
597 //printf("FileMPEG::read_frame 1 %p %d\n", frame, frame->get_color_model());
598         switch(frame->get_color_model())
599         {
600                 case MPEG3_RGB565:
601                 case MPEG3_BGR888:
602                 case MPEG3_BGRA8888:
603                 case MPEG3_RGB888:
604                 case MPEG3_RGBA8888:
605                 case MPEG3_RGBA16161616:
606                         mpeg3_read_frame(fd, 
607                                         frame->get_rows(), /* Array of pointers to the start of each output row */
608                                         0,                    /* Location in input frame to take picture */
609                                         0, 
610                                         asset->width, 
611                                         asset->height, 
612                                         asset->width,                   /* Dimensions of output_rows */
613                                         asset->height, 
614                                         frame->get_color_model(),             /* One of the color model #defines */
615                                         file->current_layer);
616                         break;
618 // Use Temp
619                 default:
620 // Read these directly
621                         if(frame->get_color_model() == src_cmodel)
622                         {
623                                 mpeg3_read_yuvframe(fd,
624                                         (char*)frame->get_y(),
625                                         (char*)frame->get_u(),
626                                         (char*)frame->get_v(),
627                                         0,
628                                         0,
629                                         asset->width,
630                                         asset->height,
631                                         file->current_layer);
632                         }
633                         else
634 // Process through temp frame
635                         {
636                                 char *y, *u, *v;
637                                 mpeg3_read_yuvframe_ptr(fd,
638                                         &y,
639                                         &u,
640                                         &v,
641                                         file->current_layer);
642                                 cmodel_transfer(frame->get_rows(), 
643                                         0,
644                                         frame->get_y(),
645                                         frame->get_u(),
646                                         frame->get_v(),
647                                         (unsigned char*)y,
648                                         (unsigned char*)u,
649                                         (unsigned char*)v,
650                                         0,
651                                         0,
652                                         asset->width,
653                                         asset->height,
654                                         0,
655                                         0,
656                                         asset->width,
657                                         asset->height,
658                                         src_cmodel, 
659                                         frame->get_color_model(),
660                                         0, 
661                                         asset->width,
662                                         frame->get_w());
663                         }
664 //printf("FileMPEG::read_frame 2\n");
665                         break;
666         }
667 //for(int i = 0; i < frame->get_w() * 3 * 20; i++) 
668 //      ((u_int16_t*)frame->get_rows()[0])[i] = 0xffff;
669 //printf("FileMPEG::read_frame 100\n");
670         return result;
673 void FileMPEG::to_streamchannel(int channel, int &stream_out, int &channel_out)
675         for(stream_out = 0, channel_out = file->current_channel; 
676                 stream_out < mpeg3_total_astreams(fd) && 
677                         channel_out >= mpeg3_audio_channels(fd, stream_out);
678                 channel_out -= mpeg3_audio_channels(fd, stream_out), stream_out++)
679         ;
682 int FileMPEG::read_samples(double *buffer, int64_t len)
684         if(!fd) return 0;
686 // This is directed to a FileMPEGBuffer
687         float *temp_float = new float[len];
688 // Translate pure channel to a stream and a channel in the mpeg stream
689         int stream, channel;
690         to_streamchannel(file->current_channel, stream, channel);
691         
692         
693         
694 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
696         mpeg3_set_sample(fd, 
697                 file->current_sample,
698                 stream);
699         mpeg3_read_audio(fd, 
700                 temp_float,      /* Pointer to pre-allocated buffer of floats */
701                 0,      /* Pointer to pre-allocated buffer of int16's */
702                 channel,          /* Channel to decode */
703                 len,         /* Number of samples to decode */
704                 stream);          /* Stream containing the channel */
707 //      last_sample = file->current_sample;
708         for(int i = 0; i < len; i++) buffer[i] = temp_float[i];
710         delete [] temp_float;
711 //printf("FileMPEG::read_samples 100\n");
712         return 0;
715 char* FileMPEG::strtocompression(char *string)
717         return "";
720 char* FileMPEG::compressiontostr(char *string)
722         return "";
731 FileMPEGVideo::FileMPEGVideo(FileMPEG *file)
732  : Thread(1, 0, 0)
734         this->file = file;
735         mpeg2enc_init_buffers();
736         mpeg2enc_set_w(file->asset->width);
737         mpeg2enc_set_h(file->asset->height);
738         mpeg2enc_set_rate(file->asset->frame_rate);
741 FileMPEGVideo::~FileMPEGVideo()
743         Thread::join();
746 void FileMPEGVideo::run()
748         mpeg2enc(file->vcommand_line.total, file->vcommand_line.values);
758 FileMPEGAudio::FileMPEGAudio(FileMPEG *file)
759  : Thread(1, 0, 0)
761         this->file = file;
762         toolame_init_buffers();
765 FileMPEGAudio::~FileMPEGAudio()
767         Thread::join();
770 void FileMPEGAudio::run()
772         file->toolame_result = toolame(file->acommand_line.total, file->acommand_line.values);
782 MPEGConfigAudio::MPEGConfigAudio(BC_WindowBase *parent_window, Asset *asset)
783  : BC_Window(PROGRAM_NAME ": Audio Compression",
784         parent_window->get_abs_cursor_x(),
785         parent_window->get_abs_cursor_y(),
786         310,
787         120,
788         -1,
789         -1,
790         0,
791         0,
792         1)
794         this->parent_window = parent_window;
795         this->asset = asset;
798 MPEGConfigAudio::~MPEGConfigAudio()
802 int MPEGConfigAudio::create_objects()
804         int x = 10, y = 10;
805         int x1 = 150;
806         MPEGLayer *layer;
808         add_tool(new BC_Title(x, y, _("Layer:")));
809         add_tool(layer = new MPEGLayer(x1, y, this));
810         layer->create_objects();
812         y += 30;
813         add_tool(new BC_Title(x, y, _("Kbits per second:")));
814         add_tool(bitrate = new MPEGABitrate(x1, y, this));
815         bitrate->create_objects();
816         
817         
818         add_subwindow(new BC_OKButton(this));
819         show_window();
820         flush();
821         return 0;
824 int MPEGConfigAudio::close_event()
826         set_done(0);
827         return 1;
836 MPEGLayer::MPEGLayer(int x, int y, MPEGConfigAudio *gui)
837  : BC_PopupMenu(x, y, 150, layer_to_string(gui->asset->ampeg_derivative))
839         this->gui = gui;
842 void MPEGLayer::create_objects()
844         add_item(new BC_MenuItem(layer_to_string(2)));
845         add_item(new BC_MenuItem(layer_to_string(3)));
848 int MPEGLayer::handle_event()
850         gui->asset->ampeg_derivative = string_to_layer(get_text());
851         gui->bitrate->set_layer(gui->asset->ampeg_derivative);
852         return 1;
855 int MPEGLayer::string_to_layer(char *string)
857         if(!strcasecmp(layer_to_string(2), string))
858                 return 2;
859         if(!strcasecmp(layer_to_string(3), string))
860                 return 3;
862         return 2;
865 char* MPEGLayer::layer_to_string(int layer)
867         switch(layer)
868         {
869                 case 2:
870                         return _("II");
871                         break;
872                 
873                 case 3:
874                         return _("III");
875                         break;
876                         
877                 default:
878                         return _("II");
879                         break;
880         }
889 MPEGABitrate::MPEGABitrate(int x, int y, MPEGConfigAudio *gui)
890  : BC_PopupMenu(x, 
891         y, 
892         150, 
893         bitrate_to_string(gui->string, gui->asset->ampeg_bitrate))
895         this->gui = gui;
898 void MPEGABitrate::create_objects()
900         set_layer(gui->asset->ampeg_derivative);
903 void MPEGABitrate::set_layer(int layer)
905         while(total_items())
906         {
907                 remove_item(0);
908         }
910         if(layer == 2)
911         {
912                 add_item(new BC_MenuItem("160"));
913                 add_item(new BC_MenuItem("192"));
914                 add_item(new BC_MenuItem("224"));
915                 add_item(new BC_MenuItem("256"));
916                 add_item(new BC_MenuItem("320"));
917                 add_item(new BC_MenuItem("384"));
918         }
919         else
920         {
921                 add_item(new BC_MenuItem("8"));
922                 add_item(new BC_MenuItem("16"));
923                 add_item(new BC_MenuItem("24"));
924                 add_item(new BC_MenuItem("32"));
925                 add_item(new BC_MenuItem("40"));
926                 add_item(new BC_MenuItem("48"));
927                 add_item(new BC_MenuItem("56"));
928                 add_item(new BC_MenuItem("64"));
929                 add_item(new BC_MenuItem("80"));
930                 add_item(new BC_MenuItem("96"));
931                 add_item(new BC_MenuItem("112"));
932                 add_item(new BC_MenuItem("128"));
933                 add_item(new BC_MenuItem("144"));
934                 add_item(new BC_MenuItem("160"));
935                 add_item(new BC_MenuItem("192"));
936                 add_item(new BC_MenuItem("224"));
937                 add_item(new BC_MenuItem("256"));
938                 add_item(new BC_MenuItem("320"));
939         }
942 int MPEGABitrate::handle_event()
944         gui->asset->ampeg_bitrate = string_to_bitrate(get_text());
945         return 1;
948 int MPEGABitrate::string_to_bitrate(char *string)
950         return atol(string);
954 char* MPEGABitrate::bitrate_to_string(char *string, int bitrate)
956         sprintf(string, "%d", bitrate);
957         return string;
968 MPEGConfigVideo::MPEGConfigVideo(BC_WindowBase *parent_window, 
969         Asset *asset)
970  : BC_Window(PROGRAM_NAME ": Video Compression",
971         parent_window->get_abs_cursor_x(),
972         parent_window->get_abs_cursor_y(),
973         500,
974         300,
975         -1,
976         -1,
977         0,
978         0,
979         1)
981         this->parent_window = parent_window;
982         this->asset = asset;
985 MPEGConfigVideo::~MPEGConfigVideo()
989 int MPEGConfigVideo::create_objects()
991         int x = 10, y = 10;
992         int x1 = x + 150;
993         int x2 = x + 300;
994         MPEGDerivative *derivative;
995         MPEGColorModel *cmodel;
997         add_subwindow(new BC_Title(x, y + 5, _("Derivative:")));
998         add_subwindow(derivative = new MPEGDerivative(x1, y, this));
999         derivative->create_objects();
1000         y += 30;
1002         add_subwindow(new BC_Title(x, y + 5, _("Bitrate:")));
1003         add_subwindow(new MPEGBitrate(x1, y, this));
1004         add_subwindow(fixed_bitrate = new MPEGFixedBitrate(x2, y, this));
1005         y += 30;
1007         add_subwindow(new BC_Title(x, y, _("Quantization:")));
1008         MPEGQuant *quant = new MPEGQuant(x1, y, this);
1009         quant->create_objects();
1010         add_subwindow(fixed_quant = new MPEGFixedQuant(x2, y, this));
1011         y += 30;
1013         add_subwindow(new BC_Title(x, y, _("I frame distance:")));
1014         MPEGIFrameDistance *iframe_distance = 
1015                 new MPEGIFrameDistance(x1, y, this);
1016         iframe_distance->create_objects();
1017         y += 30;
1019         add_subwindow(new BC_Title(x, y, _("Color model:")));
1020         add_subwindow(cmodel = new MPEGColorModel(x1, y, this));
1021         cmodel->create_objects();
1022         y += 30;
1023         
1024 //      add_subwindow(new BC_Title(x, y, _("P frame distance:")));
1025 //      y += 30;
1028         add_subwindow(new BC_CheckBox(x, y, &asset->vmpeg_progressive, _("Progressive frames")));
1029         y += 30;
1030         add_subwindow(new BC_CheckBox(x, y, &asset->vmpeg_denoise, _("Denoise")));
1031         y += 30;
1032         add_subwindow(new BC_CheckBox(x, y, &asset->vmpeg_seq_codes, _("Sequence start codes in every GOP")));
1034         add_subwindow(new BC_OKButton(this));
1035         show_window();
1036         flush();
1037         return 0;
1040 int MPEGConfigVideo::close_event()
1042         set_done(0);
1043         return 1;
1048 MPEGDerivative::MPEGDerivative(int x, int y, MPEGConfigVideo *gui)
1049  : BC_PopupMenu(x, y, 150, derivative_to_string(gui->asset->vmpeg_derivative))
1051         this->gui = gui;
1054 void MPEGDerivative::create_objects()
1056         add_item(new BC_MenuItem(derivative_to_string(1)));
1057         add_item(new BC_MenuItem(derivative_to_string(2)));
1060 int MPEGDerivative::handle_event()
1062         gui->asset->vmpeg_derivative = string_to_derivative(get_text());
1063         return 1;
1066 int MPEGDerivative::string_to_derivative(char *string)
1068         if(!strcasecmp(derivative_to_string(1), string))
1069                 return 1;
1070         if(!strcasecmp(derivative_to_string(2), string))
1071                 return 2;
1073         return 1;
1076 char* MPEGDerivative::derivative_to_string(int derivative)
1078         switch(derivative)
1079         {
1080                 case 1:
1081                         return _("MPEG-1");
1082                         break;
1083                 
1084                 case 2:
1085                         return _("MPEG-2");
1086                         break;
1087                         
1088                 default:
1089                         return _("MPEG-1");
1090                         break;
1091         }
1097 MPEGBitrate::MPEGBitrate(int x, int y, MPEGConfigVideo *gui)
1098  : BC_TextBox(x, y, 100, 1, gui->asset->vmpeg_bitrate)
1100         this->gui = gui;
1104 int MPEGBitrate::handle_event()
1106         gui->asset->vmpeg_bitrate = atol(get_text());
1107         return 1;
1114 MPEGQuant::MPEGQuant(int x, int y, MPEGConfigVideo *gui)
1115  : BC_TumbleTextBox(gui, 
1116         (int64_t)gui->asset->vmpeg_quantization, 
1117         (int64_t)1,
1118         (int64_t)100,
1119         x, 
1120         y,
1121         100)
1123         this->gui = gui;
1126 int MPEGQuant::handle_event()
1128         gui->asset->vmpeg_quantization = atol(get_text());
1129         return 1;
1132 MPEGFixedBitrate::MPEGFixedBitrate(int x, int y, MPEGConfigVideo *gui)
1133  : BC_Radial(x, y, gui->asset->vmpeg_fix_bitrate, _("Fixed bitrate"))
1135         this->gui = gui;
1138 int MPEGFixedBitrate::handle_event()
1140         update(1);
1141         gui->asset->vmpeg_fix_bitrate = 1;
1142         gui->fixed_quant->update(0);
1143         return 1;
1146 MPEGFixedQuant::MPEGFixedQuant(int x, int y, MPEGConfigVideo *gui)
1147  : BC_Radial(x, y, !gui->asset->vmpeg_fix_bitrate, _("Fixed quantization"))
1149         this->gui = gui;
1152 int MPEGFixedQuant::handle_event()
1154         update(1);
1155         gui->asset->vmpeg_fix_bitrate = 0;
1156         gui->fixed_bitrate->update(0);
1157         return 1;
1160 MPEGIFrameDistance::MPEGIFrameDistance(int x, int y, MPEGConfigVideo *gui)
1161  : BC_TumbleTextBox(gui, 
1162         (int64_t)gui->asset->vmpeg_iframe_distance, 
1163         (int64_t)1,
1164         (int64_t)100,
1165         x, 
1166         y,
1167         50)
1169         this->gui = gui;
1172 int MPEGIFrameDistance::handle_event()
1174         gui->asset->vmpeg_iframe_distance = atol(get_text());
1175         return 1;
1179 MPEGColorModel::MPEGColorModel(int x, int y, MPEGConfigVideo *gui)
1180  : BC_PopupMenu(x, y, 150, cmodel_to_string(gui->asset->vmpeg_cmodel))
1182         this->gui = gui;
1185 void MPEGColorModel::create_objects()
1187         add_item(new BC_MenuItem(cmodel_to_string(0)));
1188         add_item(new BC_MenuItem(cmodel_to_string(1)));
1191 int MPEGColorModel::handle_event()
1193         gui->asset->vmpeg_cmodel = string_to_cmodel(get_text());
1194         return 1;
1197 int MPEGColorModel::string_to_cmodel(char *string)
1199         if(!strcasecmp(cmodel_to_string(0), string))
1200                 return 0;
1201         if(!strcasecmp(cmodel_to_string(1), string))
1202                 return 1;
1204         return 1;
1207 char* MPEGColorModel::cmodel_to_string(int cmodel)
1209         switch(cmodel)
1210         {
1211                 case 0:
1212                         return _("YUV 4:2:0");
1213                         break;
1214                 
1215                 case 1:
1216                         return _("YUV 4:2:2");
1217                         break;
1218                         
1219                 default:
1220                         return _("YUV 4:2:0");
1221                         break;
1222         }