r499: This commit was manufactured by cvs2svn to create tag 'r1_2_1-last'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / filempeg.C
blob6268ed8126f718f30d3ba5f2e2c3378d7cd17d0a
1 #include "asset.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 "language.h"
10 #include "mwindow.inc"
11 #include "vframe.h"
12 #include "videodevice.inc"
14 #include <stdio.h>
15 #include <string.h>
16 #include <unistd.h>
19 FileMPEG::FileMPEG(Asset *asset, File *file)
20  : FileBase(asset, file)
22         reset_parameters();
23 // May also be VMPEG or AMPEG if write status.
24         if(asset->format == FILE_UNKNOWN) asset->format = FILE_MPEG;
25         asset->byte_order = 0;
28 FileMPEG::~FileMPEG()
30         close_file();
33 void FileMPEG::get_parameters(BC_WindowBase *parent_window, 
34         Asset *asset, 
35         BC_WindowBase* &format_window,
36         int audio_options,
37         int video_options)
39         if(audio_options && asset->format == FILE_AMPEG)
40         {
41                 MPEGConfigAudio *window = new MPEGConfigAudio(parent_window, asset);
42                 format_window = window;
43                 window->create_objects();
44                 window->run_window();
45                 delete window;
46         }
47         else
48         if(video_options && asset->format == FILE_VMPEG)
49         {
50                 MPEGConfigVideo *window = new MPEGConfigVideo(parent_window, asset);
51                 format_window = window;
52                 window->create_objects();
53                 window->run_window();
54                 delete window;
55         }
58 int FileMPEG::check_sig(Asset *asset)
60         return mpeg3_check_sig(asset->path);
63 int FileMPEG::reset_parameters_derived()
65         fd = 0;
66         video_out = 0;
67         audio_out = 0;
68         prev_track = 0;
69         temp_frame = 0;
70         toolame_temp = 0;
71         toolame_allocation = 0;
72         toolame_result = 0;
73         lame_temp[0] = 0;
74         lame_temp[1] = 0;
75         lame_allocation = 0;
76         lame_global = 0;
77         lame_output = 0;
78         lame_output_allocation = 0;
79         lame_fd = 0;
80         lame_started = 0;
84 // Just create the Quicktime objects since this routine is also called
85 // for reopening.
86 int FileMPEG::open_file(int rd, int wr)
88         int result = 0;
89         this->rd = rd;
90         this->wr = wr;
92         if(rd)
93         {
94                 if(!(fd = mpeg3_open(asset->path)))
95                 {
96                         printf("FileMPEG::open_file %s\n", asset->path);
97                         result = 1;
98                 }
99                 else
100                 {
101                         mpeg3_set_cpus(fd, file->cpus);
102                         mpeg3_set_mmx(fd, 0);
104                         asset->audio_data = mpeg3_has_audio(fd);
105                         if(asset->audio_data)
106                         {
107                                 asset->channels = 0;
108                                 for(int i = 0; i < mpeg3_total_astreams(fd); i++)
109                                 {
110                                         asset->channels += mpeg3_audio_channels(fd, i);
111                                 }
112                                 if(!asset->sample_rate)
113                                         asset->sample_rate = mpeg3_sample_rate(fd, 0);
114                                 asset->audio_length = mpeg3_audio_samples(fd, 0); 
115                         }
117                         asset->video_data = mpeg3_has_video(fd);
118                         if(asset->video_data)
119                         {
120                                 asset->layers = mpeg3_total_vstreams(fd);
121                                 asset->width = mpeg3_video_width(fd, 0);
122                                 asset->height = mpeg3_video_height(fd, 0);
123                                 asset->video_length = mpeg3_video_frames(fd, 0);
124                                 asset->vmpeg_cmodel = (mpeg3_colormodel(fd, 0) == MPEG3_YUV422P) ? 1 : 0;
125                                 if(!asset->frame_rate)
126                                         asset->frame_rate = mpeg3_frame_rate(fd, 0);
127                         }
128                 }
129         }
130         
131         
132         
133         if(wr && asset->format == FILE_VMPEG)
134         {
135                 char bitrate_string[BCTEXTLEN];
136                 char quant_string[BCTEXTLEN];
137                 char iframe_string[BCTEXTLEN];
139                 sprintf(bitrate_string, "%d", asset->vmpeg_bitrate);
140                 sprintf(quant_string, "%d", asset->vmpeg_quantization);
141                 sprintf(iframe_string, "%d", asset->vmpeg_iframe_distance);
143 // Construct command line
144                 if(!result)
145                 {
146                         append_vcommand_line("mpeg2enc");
149                         if(asset->aspect_ratio > 0)
150                         {
151                                 append_vcommand_line("-a");
152                                 if(EQUIV(asset->aspect_ratio, 1.333))
153                                         append_vcommand_line("2");
154                                 else
155                                 if(EQUIV(asset->aspect_ratio, 1.777))
156                                         append_vcommand_line("3");
157                                 else
158                                 if(EQUIV(asset->aspect_ratio, 2.11))
159                                         append_vcommand_line("4");
160                         }
162                         append_vcommand_line(asset->vmpeg_derivative == 1 ? "-1" : "");
163                         append_vcommand_line(asset->vmpeg_cmodel == 1 ? "-422" : "");
164                         if(asset->vmpeg_fix_bitrate)
165                         {
166                                 append_vcommand_line("-b");
167                                 append_vcommand_line(bitrate_string);
168                         }
169                         else
170                         {
171                                 append_vcommand_line("-q");
172                                 append_vcommand_line(quant_string);
173                         }
174                         append_vcommand_line(!asset->vmpeg_fix_bitrate ? quant_string : "");
175                         append_vcommand_line("-n");
176                         append_vcommand_line(iframe_string);
177                         append_vcommand_line(asset->vmpeg_progressive ? "-p" : "");
178                         append_vcommand_line(asset->vmpeg_denoise ? "-d" : "");
179                         append_vcommand_line(file->cpus <= 1 ? "-u" : "");
180                         append_vcommand_line(asset->vmpeg_seq_codes ? "-g" : "");
181                         append_vcommand_line(asset->path);
183                         video_out = new FileMPEGVideo(this);
184                         video_out->start();
185                 }
186         }
188         if(wr && asset->format == FILE_AMPEG)
189         {
190                 char command_line[BCTEXTLEN];
191                 char encoder_string[BCTEXTLEN];
192                 char argument_string[BCTEXTLEN];
194 //printf("FileMPEG::open_file 1 %d\n", asset->ampeg_derivative);
195                 encoder_string[0] = 0;
197                 if(asset->ampeg_derivative == 2)
198                 {
199                         char string[BCTEXTLEN];
200                         append_acommand_line("toolame");
201                         append_acommand_line("-m");
202                         append_acommand_line((asset->channels >= 2) ? "j" : "m");
203                         sprintf(string, "%f", (float)asset->sample_rate / 1000);
204                         append_acommand_line("-s");
205                         append_acommand_line(string);
206                         sprintf(string, "%d", asset->ampeg_bitrate);
207                         append_acommand_line("-b");
208                         append_acommand_line(string);
209                         append_acommand_line("-");
210                         append_acommand_line(asset->path);
212                         audio_out = new FileMPEGAudio(this);
213                         audio_out->start();
214                 }
215                 else
216                 if(asset->ampeg_derivative == 3)
217                 {
218                         lame_global = lame_init();
219                         lame_set_brate(lame_global, asset->ampeg_bitrate / 1000);
220                         lame_set_quality(lame_global, 0);
221                         lame_set_in_samplerate(lame_global, 
222                                 asset->sample_rate);
223                         if((result = lame_init_params(lame_global)) < 0)
224                         {
225                                 printf(_("encode: lame_init_params returned %d\n"), result);
226                                 lame_close(lame_global);
227                                 lame_global = 0;
228                         }
229                         else
230                         if(!(lame_fd = fopen(asset->path, "w")))
231                         {
232                                 perror("FileMPEG::open_file");
233                                 lame_close(lame_global);
234                                 lame_global = 0;
235                         }
236                 }
237                 else
238                 {
239                         printf("FileMPEG::open_file: ampeg_derivative=%d\n", asset->ampeg_derivative);
240                         result = 1;
241                 }
242         }
244 //asset->dump();
245 //printf("FileMPEG::open_file 100\n");
246         return result;
249 void FileMPEG::append_vcommand_line(const char *string)
251         if(string[0])
252         {
253                 char *argv = strdup(string);
254                 vcommand_line.append(argv);
255         }
258 void FileMPEG::append_acommand_line(const char *string)
260         if(string[0])
261         {
262                 char *argv = strdup(string);
263                 acommand_line.append(argv);
264         }
268 int FileMPEG::close_file()
270 //printf("FileMPEG::close_file 1\n");
271         if(fd)
272         {
273                 mpeg3_close(fd);
274         }
276         if(video_out)
277         {
278 // End of sequence signal
279                 mpeg2enc_set_input_buffers(1, 0, 0, 0);
280                 delete video_out;
281                 video_out = 0;
282         }
284         vcommand_line.remove_all_objects();
285         acommand_line.remove_all_objects();
287         if(audio_out)
288         {
289                 toolame_send_buffer(0, 0);
290                 delete audio_out;
291                 audio_out = 0;
292         }
294         if(lame_global)
295                 lame_close(lame_global);
297         if(temp_frame) delete temp_frame;
298         if(toolame_temp) delete [] toolame_temp;
300         if(lame_temp[0]) delete [] lame_temp[0];
301         if(lame_temp[1]) delete [] lame_temp[1];
302         if(lame_output) delete [] lame_output;
303         if(lame_fd) fclose(lame_fd);
305         reset_parameters();
306         FileBase::close_file();
307 //printf("FileMPEG::close_file 100\n");
308         return 0;
311 int FileMPEG::get_best_colormodel(Asset *asset, int driver)
313 //printf("FileMPEG::get_best_colormodel 1\n");
314         switch(driver)
315         {
316                 case PLAYBACK_X11:
317                         return BC_RGB888;
318                         if(asset->vmpeg_cmodel == 0) return BC_YUV420P;
319                         if(asset->vmpeg_cmodel == 1) return BC_YUV422P;
320                         break;
321                 case PLAYBACK_X11_XV:
322                         if(asset->vmpeg_cmodel == 0) return BC_YUV420P;
323                         if(asset->vmpeg_cmodel == 1) return BC_YUV422P;
324                         break;
325                 case PLAYBACK_LML:
326                 case PLAYBACK_BUZ:
327                         return BC_YUV422P;
328                         break;
329                 case PLAYBACK_DV1394:
330                 case PLAYBACK_FIREWIRE:
331                         return BC_YUV422P;
332                         break;
333                 case VIDEO4LINUX:
334                 case VIDEO4LINUX2:
335                         if(asset->vmpeg_cmodel == 0) return BC_YUV420P;
336                         if(asset->vmpeg_cmodel == 1) return BC_YUV422P;
337                         break;
338                 case CAPTURE_BUZ:
339                 case CAPTURE_LML:
340                         return BC_YUV422;
341                         break;
342                 case CAPTURE_FIREWIRE:
343                         return BC_YUV422P;
344                         break;
345         }
346 //printf("FileMPEG::get_best_colormodel 100\n");
349 int FileMPEG::colormodel_supported(int colormodel)
351         return colormodel;
355 int FileMPEG::can_copy_from(Edit *edit, int64_t position)
357         if(!fd) return 0;
358         return 0;
361 int FileMPEG::set_audio_position(int64_t sample)
363 #if 0
364         if(!fd) return 1;
365         
366         int channel, stream;
367         to_streamchannel(file->current_channel, stream, channel);
369 //printf("FileMPEG::set_audio_position %d %d %d\n", sample, mpeg3_get_sample(fd, stream), last_sample);
370         if(sample != mpeg3_get_sample(fd, stream) &&
371                 sample != last_sample)
372         {
373                 if(sample >= 0 && sample < asset->audio_length)
374                 {
375 //printf("FileMPEG::set_audio_position seeking stream %d\n", sample);
376                         return mpeg3_set_sample(fd, sample, stream);
377                 }
378                 else
379                         return 1;
380         }
381 #endif
382         return 0;
385 int FileMPEG::set_video_position(int64_t x)
387         if(!fd) return 1;
388         if(x >= 0 && x < asset->video_length)
389         {
390                 mpeg3_set_frame(fd, x, file->current_layer);
391         }
392         else
393                 return 1;
397 int FileMPEG::write_samples(double **buffer, int64_t len)
399         int result = 0;
401 //printf("FileMPEG::write_samples 1\n");
402         if(asset->ampeg_derivative == 2)
403         {
404 // Convert to int16
405                 int channels = MIN(asset->channels, 2);
406                 int64_t audio_size = len * channels * 2;
407                 if(toolame_allocation < audio_size)
408                 {
409                         if(toolame_temp) delete [] toolame_temp;
410                         toolame_temp = new unsigned char[audio_size];
411                         toolame_allocation = audio_size;
412                 }
414                 for(int i = 0; i < channels; i++)
415                 {
416                         int16_t *output = ((int16_t*)toolame_temp) + i;
417                         double *input = buffer[i];
418                         for(int j = 0; j < len; j++)
419                         {
420                                 int sample = (int)(*input * 0x7fff);
421                                 *output = (int16_t)(CLIP(sample, -0x8000, 0x7fff));
422                                 output += channels;
423                                 input++;
424                         }
425                 }
426                 result = toolame_send_buffer((char*)toolame_temp, audio_size);
427         }
428         else
429         if(asset->ampeg_derivative == 3)
430         {
431                 int channels = MIN(asset->channels, 2);
432                 int64_t audio_size = len * channels;
433                 if(!lame_global) return 1;
434                 if(!lame_fd) return 1;
435                 if(lame_allocation < audio_size)
436                 {
437                         if(lame_temp[0]) delete [] lame_temp[0];
438                         if(lame_temp[1]) delete [] lame_temp[1];
439                         lame_temp[0] = new float[audio_size];
440                         lame_temp[1] = new float[audio_size];
441                         lame_allocation = audio_size;
442                 }
444                 if(lame_output_allocation < audio_size * 4)
445                 {
446                         if(lame_output) delete [] lame_output;
447                         lame_output_allocation = audio_size * 4;
448                         lame_output = new char[lame_output_allocation];
449                 }
451                 for(int i = 0; i < channels; i++)
452                 {
453                         float *output = lame_temp[i];
454                         double *input = buffer[i];
455                         for(int j = 0; j < len; j++)
456                         {
457                                 *output++ = *input++ * (float)32768;
458                         }
459                 }
461                 result = lame_encode_buffer_float(lame_global,
462                         lame_temp[0],
463                         (channels > 1) ? lame_temp[1] : lame_temp[0],
464                         len,
465                         (unsigned char*)lame_output,
466                         lame_output_allocation);
467                 if(result > 0)
468                 {
469                         char *real_output = lame_output;
470                         int bytes = result;
471                         if(!lame_started)
472                         {
473                                 for(int i = 0; i < bytes; i++)
474                                         if(lame_output[i])
475                                         {
476                                                 real_output = &lame_output[i];
477                                                 lame_started = 1;
478                                                 bytes -= i;
479                                                 break;
480                                         }
481                         }
482                         if(bytes > 0 && lame_started)
483                         {
484                                 result = !fwrite(real_output, 1, bytes, lame_fd);
485                                 if(result)
486                                         perror("FileMPEG::write_samples");
487                         }
488                         else
489                                 result = 0;
490                 }
491                 else
492                         result = 1;
493         }
495         return result;
498 int FileMPEG::write_frames(VFrame ***frames, int len)
500         int result = 0;
502         if(video_out)
503         {
504                 int temp_w = (int)((asset->width + 15) / 16) * 16;
505                 int temp_h;
506                 int output_cmodel = 
507                         (asset->vmpeg_cmodel == 0) ? BC_YUV420P : BC_YUV422P;
508                 
509                 
510 // Height depends on progressiveness
511                 if(asset->vmpeg_progressive || asset->vmpeg_derivative == 1)
512                         temp_h = (int)((asset->height + 15) / 16) * 16;
513                 else
514                         temp_h = (int)((asset->height + 31) / 32) * 32;
516 //printf("FileMPEG::write_frames 1\n");
517                 
518 // Only 1 layer is supported in MPEG output
519                 for(int i = 0; i < 1; i++)
520                 {
521                         for(int j = 0; j < len; j++)
522                         {
523                                 VFrame *frame = frames[i][j];
524                                 
525                                 
526                                 
527                                 if(frame->get_w() == temp_w &&
528                                         frame->get_h() == temp_h &&
529                                         frame->get_color_model() == output_cmodel)
530                                 {
531                                         mpeg2enc_set_input_buffers(0, 
532                                                 (char*)frame->get_y(),
533                                                 (char*)frame->get_u(),
534                                                 (char*)frame->get_v());
535                                 }
536                                 else
537                                 {
538 //printf("FileMPEG::write_frames 2\n");
539                                         if(temp_frame &&
540                                                 (temp_frame->get_w() != temp_w ||
541                                                 temp_frame->get_h() != temp_h ||
542                                                 temp_frame->get_color_model() || output_cmodel))
543                                         {
544                                                 delete temp_frame;
545                                                 temp_frame = 0;
546                                         }
547 //printf("FileMPEG::write_frames 3\n");
550                                         if(!temp_frame)
551                                         {
552                                                 temp_frame = new VFrame(0, 
553                                                         temp_w, 
554                                                         temp_h, 
555                                                         output_cmodel);
556                                         }
558                                         cmodel_transfer(temp_frame->get_rows(), 
559                                                 frame->get_rows(),
560                                                 temp_frame->get_y(),
561                                                 temp_frame->get_u(),
562                                                 temp_frame->get_v(),
563                                                 frame->get_y(),
564                                                 frame->get_u(),
565                                                 frame->get_v(),
566                                                 0,
567                                                 0,
568                                                 asset->width,
569                                                 asset->height,
570                                                 0,
571                                                 0,
572                                                 asset->width,
573                                                 asset->height,
574                                                 frame->get_color_model(), 
575                                                 temp_frame->get_color_model(),
576                                                 0, 
577                                                 frame->get_w(),
578                                                 temp_w);
580                                         mpeg2enc_set_input_buffers(0, 
581                                                 (char*)temp_frame->get_y(),
582                                                 (char*)temp_frame->get_u(),
583                                                 (char*)temp_frame->get_v());
584                                 }
585                         }
586                 }
587         }
589 //printf("FileMPEG::write_frames 100\n");
592         return result;
595 int FileMPEG::read_frame(VFrame *frame)
597         if(!fd) return 1;
598         int result = 0;
599         int src_cmodel;
601 //printf("FileMPEG::read_frame 1\n");
602         if(mpeg3_colormodel(fd, 0) == MPEG3_YUV420P)
603                 src_cmodel = BC_YUV420P;
604         else
605         if(mpeg3_colormodel(fd, 0) == MPEG3_YUV422P)
606                 src_cmodel = BC_YUV422P;
608 //printf("FileMPEG::read_frame 1 %p %d\n", frame, frame->get_color_model());
609         switch(frame->get_color_model())
610         {
611                 case MPEG3_RGB565:
612                 case MPEG3_BGR888:
613                 case MPEG3_BGRA8888:
614                 case MPEG3_RGB888:
615                 case MPEG3_RGBA8888:
616                 case MPEG3_RGBA16161616:
617                         mpeg3_read_frame(fd, 
618                                         frame->get_rows(), /* Array of pointers to the start of each output row */
619                                         0,                    /* Location in input frame to take picture */
620                                         0, 
621                                         asset->width, 
622                                         asset->height, 
623                                         asset->width,                   /* Dimensions of output_rows */
624                                         asset->height, 
625                                         frame->get_color_model(),             /* One of the color model #defines */
626                                         file->current_layer);
627                         break;
629 // Use Temp
630                 default:
631 // Read these directly
632                         if(frame->get_color_model() == src_cmodel)
633                         {
634                                 mpeg3_read_yuvframe(fd,
635                                         (char*)frame->get_y(),
636                                         (char*)frame->get_u(),
637                                         (char*)frame->get_v(),
638                                         0,
639                                         0,
640                                         asset->width,
641                                         asset->height,
642                                         file->current_layer);
643                         }
644                         else
645 // Process through temp frame
646                         {
647                                 char *y, *u, *v;
648                                 mpeg3_read_yuvframe_ptr(fd,
649                                         &y,
650                                         &u,
651                                         &v,
652                                         file->current_layer);
653                                 if(y && u && v)
654                                 {
655                                         cmodel_transfer(frame->get_rows(), 
656                                                 0,
657                                                 frame->get_y(),
658                                                 frame->get_u(),
659                                                 frame->get_v(),
660                                                 (unsigned char*)y,
661                                                 (unsigned char*)u,
662                                                 (unsigned char*)v,
663                                                 0,
664                                                 0,
665                                                 asset->width,
666                                                 asset->height,
667                                                 0,
668                                                 0,
669                                                 asset->width,
670                                                 asset->height,
671                                                 src_cmodel, 
672                                                 frame->get_color_model(),
673                                                 0, 
674                                                 asset->width,
675                                                 frame->get_w());
676                                 }
677                         }
678 //printf("FileMPEG::read_frame 2\n");
679                         break;
680         }
681 //for(int i = 0; i < frame->get_w() * 3 * 20; i++) 
682 //      ((u_int16_t*)frame->get_rows()[0])[i] = 0xffff;
683 //printf("FileMPEG::read_frame 100\n");
684         return result;
687 void FileMPEG::to_streamchannel(int channel, int &stream_out, int &channel_out)
689         for(stream_out = 0, channel_out = file->current_channel; 
690                 stream_out < mpeg3_total_astreams(fd) && 
691                         channel_out >= mpeg3_audio_channels(fd, stream_out);
692                 channel_out -= mpeg3_audio_channels(fd, stream_out), stream_out++)
693         ;
696 int FileMPEG::read_samples(double *buffer, int64_t len)
698         if(!fd) return 0;
700 // This is directed to a FileMPEGBuffer
701         float *temp_float = new float[len];
702 // Translate pure channel to a stream and a channel in the mpeg stream
703         int stream, channel;
704         to_streamchannel(file->current_channel, stream, channel);
705         
706         
707         
708 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
710         mpeg3_set_sample(fd, 
711                 file->current_sample,
712                 stream);
713         mpeg3_read_audio(fd, 
714                 temp_float,      /* Pointer to pre-allocated buffer of floats */
715                 0,      /* Pointer to pre-allocated buffer of int16's */
716                 channel,          /* Channel to decode */
717                 len,         /* Number of samples to decode */
718                 stream);          /* Stream containing the channel */
721 //      last_sample = file->current_sample;
722         for(int i = 0; i < len; i++) buffer[i] = temp_float[i];
724         delete [] temp_float;
725 //printf("FileMPEG::read_samples 100\n");
726         return 0;
729 int FileMPEG::prefer_samples_float()
731         return 1;
734 int FileMPEG::read_samples_float(float *buffer, int64_t len)
736         if(!fd) return 0;
738 // Translate pure channel to a stream and a channel in the mpeg stream
739         int stream, channel;
740         to_streamchannel(file->current_channel, stream, channel);
741         
742         
743 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
745         mpeg3_set_sample(fd, 
746                 file->current_sample,
747                 stream);
748         mpeg3_read_audio(fd, 
749                 buffer,         /* Pointer to pre-allocated buffer of floats */
750                 0,              /* Pointer to pre-allocated buffer of int16's */
751                 channel,          /* Channel to decode */
752                 len,         /* Number of samples to decode */
753                 stream);          /* Stream containing the channel */
756 //      last_sample = file->current_sample;
758 //printf("FileMPEG::read_samples 100\n");
759         return 0;
764 char* FileMPEG::strtocompression(char *string)
766         return "";
769 char* FileMPEG::compressiontostr(char *string)
771         return "";
780 FileMPEGVideo::FileMPEGVideo(FileMPEG *file)
781  : Thread(1, 0, 0)
783         this->file = file;
784         mpeg2enc_init_buffers();
785         mpeg2enc_set_w(file->asset->width);
786         mpeg2enc_set_h(file->asset->height);
787         mpeg2enc_set_rate(file->asset->frame_rate);
790 FileMPEGVideo::~FileMPEGVideo()
792         Thread::join();
795 void FileMPEGVideo::run()
797 printf("FileMPEGVideo::run ");
798 for(int i = 0; i < file->vcommand_line.total; i++)
799         printf("%s ", file->vcommand_line.values[i]);
800 printf("\n");
801         mpeg2enc(file->vcommand_line.total, file->vcommand_line.values);
811 FileMPEGAudio::FileMPEGAudio(FileMPEG *file)
812  : Thread(1, 0, 0)
814         this->file = file;
815         toolame_init_buffers();
818 FileMPEGAudio::~FileMPEGAudio()
820         Thread::join();
823 void FileMPEGAudio::run()
825         file->toolame_result = toolame(file->acommand_line.total, file->acommand_line.values);
835 MPEGConfigAudio::MPEGConfigAudio(BC_WindowBase *parent_window, Asset *asset)
836  : BC_Window(PROGRAM_NAME ": Audio Compression",
837         parent_window->get_abs_cursor_x(1),
838         parent_window->get_abs_cursor_y(1),
839         310,
840         120,
841         -1,
842         -1,
843         0,
844         0,
845         1)
847         this->parent_window = parent_window;
848         this->asset = asset;
851 MPEGConfigAudio::~MPEGConfigAudio()
855 int MPEGConfigAudio::create_objects()
857         int x = 10, y = 10;
858         int x1 = 150;
859         MPEGLayer *layer;
861         add_tool(new BC_Title(x, y, _("Layer:")));
862         add_tool(layer = new MPEGLayer(x1, y, this));
863         layer->create_objects();
865         y += 30;
866         add_tool(new BC_Title(x, y, _("Kbits per second:")));
867         add_tool(bitrate = new MPEGABitrate(x1, y, this));
868         bitrate->create_objects();
869         
870         
871         add_subwindow(new BC_OKButton(this));
872         show_window();
873         flush();
874         return 0;
877 int MPEGConfigAudio::close_event()
879         set_done(0);
880         return 1;
889 MPEGLayer::MPEGLayer(int x, int y, MPEGConfigAudio *gui)
890  : BC_PopupMenu(x, y, 150, layer_to_string(gui->asset->ampeg_derivative))
892         this->gui = gui;
895 void MPEGLayer::create_objects()
897         add_item(new BC_MenuItem(layer_to_string(2)));
898         add_item(new BC_MenuItem(layer_to_string(3)));
901 int MPEGLayer::handle_event()
903         gui->asset->ampeg_derivative = string_to_layer(get_text());
904         gui->bitrate->set_layer(gui->asset->ampeg_derivative);
905         return 1;
908 int MPEGLayer::string_to_layer(char *string)
910         if(!strcasecmp(layer_to_string(2), string))
911                 return 2;
912         if(!strcasecmp(layer_to_string(3), string))
913                 return 3;
915         return 2;
918 char* MPEGLayer::layer_to_string(int layer)
920         switch(layer)
921         {
922                 case 2:
923                         return _("II");
924                         break;
925                 
926                 case 3:
927                         return _("III");
928                         break;
929                         
930                 default:
931                         return _("II");
932                         break;
933         }
942 MPEGABitrate::MPEGABitrate(int x, int y, MPEGConfigAudio *gui)
943  : BC_PopupMenu(x, 
944         y, 
945         150, 
946         bitrate_to_string(gui->string, gui->asset->ampeg_bitrate))
948         this->gui = gui;
951 void MPEGABitrate::create_objects()
953         set_layer(gui->asset->ampeg_derivative);
956 void MPEGABitrate::set_layer(int layer)
958         while(total_items())
959         {
960                 remove_item(0);
961         }
963         if(layer == 2)
964         {
965                 add_item(new BC_MenuItem("160"));
966                 add_item(new BC_MenuItem("192"));
967                 add_item(new BC_MenuItem("224"));
968                 add_item(new BC_MenuItem("256"));
969                 add_item(new BC_MenuItem("320"));
970                 add_item(new BC_MenuItem("384"));
971         }
972         else
973         {
974                 add_item(new BC_MenuItem("8"));
975                 add_item(new BC_MenuItem("16"));
976                 add_item(new BC_MenuItem("24"));
977                 add_item(new BC_MenuItem("32"));
978                 add_item(new BC_MenuItem("40"));
979                 add_item(new BC_MenuItem("48"));
980                 add_item(new BC_MenuItem("56"));
981                 add_item(new BC_MenuItem("64"));
982                 add_item(new BC_MenuItem("80"));
983                 add_item(new BC_MenuItem("96"));
984                 add_item(new BC_MenuItem("112"));
985                 add_item(new BC_MenuItem("128"));
986                 add_item(new BC_MenuItem("144"));
987                 add_item(new BC_MenuItem("160"));
988                 add_item(new BC_MenuItem("192"));
989                 add_item(new BC_MenuItem("224"));
990                 add_item(new BC_MenuItem("256"));
991                 add_item(new BC_MenuItem("320"));
992         }
995 int MPEGABitrate::handle_event()
997         gui->asset->ampeg_bitrate = string_to_bitrate(get_text());
998         return 1;
1001 int MPEGABitrate::string_to_bitrate(char *string)
1003         return atol(string);
1007 char* MPEGABitrate::bitrate_to_string(char *string, int bitrate)
1009         sprintf(string, "%d", bitrate);
1010         return string;
1021 MPEGConfigVideo::MPEGConfigVideo(BC_WindowBase *parent_window, 
1022         Asset *asset)
1023  : BC_Window(PROGRAM_NAME ": Video Compression",
1024         parent_window->get_abs_cursor_x(1),
1025         parent_window->get_abs_cursor_y(1),
1026         500,
1027         300,
1028         -1,
1029         -1,
1030         0,
1031         0,
1032         1)
1034         this->parent_window = parent_window;
1035         this->asset = asset;
1038 MPEGConfigVideo::~MPEGConfigVideo()
1042 int MPEGConfigVideo::create_objects()
1044         int x = 10, y = 10;
1045         int x1 = x + 150;
1046         int x2 = x + 300;
1047         MPEGDerivative *derivative;
1048         MPEGColorModel *cmodel;
1050         add_subwindow(new BC_Title(x, y + 5, _("Derivative:")));
1051         add_subwindow(derivative = new MPEGDerivative(x1, y, this));
1052         derivative->create_objects();
1053         y += 30;
1055         add_subwindow(new BC_Title(x, y + 5, _("Bitrate:")));
1056         add_subwindow(new MPEGBitrate(x1, y, this));
1057         add_subwindow(fixed_bitrate = new MPEGFixedBitrate(x2, y, this));
1058         y += 30;
1060         add_subwindow(new BC_Title(x, y, _("Quantization:")));
1061         MPEGQuant *quant = new MPEGQuant(x1, y, this);
1062         quant->create_objects();
1063         add_subwindow(fixed_quant = new MPEGFixedQuant(x2, y, this));
1064         y += 30;
1066         add_subwindow(new BC_Title(x, y, _("I frame distance:")));
1067         MPEGIFrameDistance *iframe_distance = 
1068                 new MPEGIFrameDistance(x1, y, this);
1069         iframe_distance->create_objects();
1070         y += 30;
1072         add_subwindow(new BC_Title(x, y, _("Color model:")));
1073         add_subwindow(cmodel = new MPEGColorModel(x1, y, this));
1074         cmodel->create_objects();
1075         y += 30;
1076         
1077 //      add_subwindow(new BC_Title(x, y, _("P frame distance:")));
1078 //      y += 30;
1081         add_subwindow(new BC_CheckBox(x, y, &asset->vmpeg_progressive, _("Progressive frames")));
1082         y += 30;
1083         add_subwindow(new BC_CheckBox(x, y, &asset->vmpeg_denoise, _("Denoise")));
1084         y += 30;
1085         add_subwindow(new BC_CheckBox(x, y, &asset->vmpeg_seq_codes, _("Sequence start codes in every GOP")));
1087         add_subwindow(new BC_OKButton(this));
1088         show_window();
1089         flush();
1090         return 0;
1093 int MPEGConfigVideo::close_event()
1095         set_done(0);
1096         return 1;
1101 MPEGDerivative::MPEGDerivative(int x, int y, MPEGConfigVideo *gui)
1102  : BC_PopupMenu(x, y, 150, derivative_to_string(gui->asset->vmpeg_derivative))
1104         this->gui = gui;
1107 void MPEGDerivative::create_objects()
1109         add_item(new BC_MenuItem(derivative_to_string(1)));
1110         add_item(new BC_MenuItem(derivative_to_string(2)));
1113 int MPEGDerivative::handle_event()
1115         gui->asset->vmpeg_derivative = string_to_derivative(get_text());
1116         return 1;
1119 int MPEGDerivative::string_to_derivative(char *string)
1121         if(!strcasecmp(derivative_to_string(1), string))
1122                 return 1;
1123         if(!strcasecmp(derivative_to_string(2), string))
1124                 return 2;
1126         return 1;
1129 char* MPEGDerivative::derivative_to_string(int derivative)
1131         switch(derivative)
1132         {
1133                 case 1:
1134                         return _("MPEG-1");
1135                         break;
1136                 
1137                 case 2:
1138                         return _("MPEG-2");
1139                         break;
1140                         
1141                 default:
1142                         return _("MPEG-1");
1143                         break;
1144         }
1150 MPEGBitrate::MPEGBitrate(int x, int y, MPEGConfigVideo *gui)
1151  : BC_TextBox(x, y, 100, 1, gui->asset->vmpeg_bitrate)
1153         this->gui = gui;
1157 int MPEGBitrate::handle_event()
1159         gui->asset->vmpeg_bitrate = atol(get_text());
1160         return 1;
1167 MPEGQuant::MPEGQuant(int x, int y, MPEGConfigVideo *gui)
1168  : BC_TumbleTextBox(gui, 
1169         (int64_t)gui->asset->vmpeg_quantization, 
1170         (int64_t)1,
1171         (int64_t)100,
1172         x, 
1173         y,
1174         100)
1176         this->gui = gui;
1179 int MPEGQuant::handle_event()
1181         gui->asset->vmpeg_quantization = atol(get_text());
1182         return 1;
1185 MPEGFixedBitrate::MPEGFixedBitrate(int x, int y, MPEGConfigVideo *gui)
1186  : BC_Radial(x, y, gui->asset->vmpeg_fix_bitrate, _("Fixed bitrate"))
1188         this->gui = gui;
1191 int MPEGFixedBitrate::handle_event()
1193         update(1);
1194         gui->asset->vmpeg_fix_bitrate = 1;
1195         gui->fixed_quant->update(0);
1196         return 1;
1199 MPEGFixedQuant::MPEGFixedQuant(int x, int y, MPEGConfigVideo *gui)
1200  : BC_Radial(x, y, !gui->asset->vmpeg_fix_bitrate, _("Fixed quantization"))
1202         this->gui = gui;
1205 int MPEGFixedQuant::handle_event()
1207         update(1);
1208         gui->asset->vmpeg_fix_bitrate = 0;
1209         gui->fixed_bitrate->update(0);
1210         return 1;
1213 MPEGIFrameDistance::MPEGIFrameDistance(int x, int y, MPEGConfigVideo *gui)
1214  : BC_TumbleTextBox(gui, 
1215         (int64_t)gui->asset->vmpeg_iframe_distance, 
1216         (int64_t)1,
1217         (int64_t)100,
1218         x, 
1219         y,
1220         50)
1222         this->gui = gui;
1225 int MPEGIFrameDistance::handle_event()
1227         gui->asset->vmpeg_iframe_distance = atol(get_text());
1228         return 1;
1232 MPEGColorModel::MPEGColorModel(int x, int y, MPEGConfigVideo *gui)
1233  : BC_PopupMenu(x, y, 150, cmodel_to_string(gui->asset->vmpeg_cmodel))
1235         this->gui = gui;
1238 void MPEGColorModel::create_objects()
1240         add_item(new BC_MenuItem(cmodel_to_string(0)));
1241         add_item(new BC_MenuItem(cmodel_to_string(1)));
1244 int MPEGColorModel::handle_event()
1246         gui->asset->vmpeg_cmodel = string_to_cmodel(get_text());
1247         return 1;
1250 int MPEGColorModel::string_to_cmodel(char *string)
1252         if(!strcasecmp(cmodel_to_string(0), string))
1253                 return 0;
1254         if(!strcasecmp(cmodel_to_string(1), string))
1255                 return 1;
1257         return 1;
1260 char* MPEGColorModel::cmodel_to_string(int cmodel)
1262         switch(cmodel)
1263         {
1264                 case 0:
1265                         return _("YUV 4:2:0");
1266                         break;
1267                 
1268                 case 1:
1269                         return _("YUV 4:2:2");
1270                         break;
1271                         
1272                 default:
1273                         return _("YUV 4:2:0");
1274                         break;
1275         }