r602: Fix baver's code... don't insert timecode when show_tc is not set
[cinelerra_cv/mob.git] / cinelerra / filempeg.C
blobc7ce5b0a8441101241e69ba219081cfcf6dd9327
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 "interlacemodes.h"
10 #include "language.h"
11 #include "libmjpeg.h"
12 #include "mwindow.inc"
13 #include "vframe.h"
14 #include "videodevice.inc"
16 #include <stdio.h>
17 #include <string.h>
18 #include <unistd.h>
21 FileMPEG::FileMPEG(Asset *asset, File *file)
22  : FileBase(asset, file)
24         reset_parameters();
25 // May also be VMPEG or AMPEG if write status.
26         if(asset->format == FILE_UNKNOWN) asset->format = FILE_MPEG;
27         asset->byte_order = 0;
30 FileMPEG::~FileMPEG()
32         close_file();
35 void FileMPEG::get_parameters(BC_WindowBase *parent_window, 
36         Asset *asset, 
37         BC_WindowBase* &format_window,
38         int audio_options,
39         int video_options)
41         if(audio_options && asset->format == FILE_AMPEG)
42         {
43                 MPEGConfigAudio *window = new MPEGConfigAudio(parent_window, asset);
44                 format_window = window;
45                 window->create_objects();
46                 window->run_window();
47                 delete window;
48         }
49         else
50         if(video_options && asset->format == FILE_VMPEG)
51         {
52                 MPEGConfigVideo *window = new MPEGConfigVideo(parent_window, asset);
53                 format_window = window;
54                 window->create_objects();
55                 window->run_window();
56                 delete window;
57         }
60 int FileMPEG::check_sig(Asset *asset)
62         return mpeg3_check_sig(asset->path);
65 int FileMPEG::reset_parameters_derived()
67         fd = 0;
68         video_out = 0;
69         audio_out = 0;
70         prev_track = 0;
71         temp_frame = 0;
72         toolame_temp = 0;
73         toolame_allocation = 0;
74         toolame_result = 0;
75         lame_temp[0] = 0;
76         lame_temp[1] = 0;
77         lame_allocation = 0;
78         lame_global = 0;
79         lame_output = 0;
80         lame_output_allocation = 0;
81         lame_fd = 0;
82         lame_started = 0;
86 // Just create the Quicktime objects since this routine is also called
87 // for reopening.
88 int FileMPEG::open_file(int rd, int wr)
90         int result = 0;
91         this->rd = rd;
92         this->wr = wr;
94         if(rd)
95         {
96                 if(!(fd = mpeg3_open(asset->path)))
97                 {
98                         printf("FileMPEG::open_file %s\n", asset->path);
99                         result = 1;
100                 }
101                 else
102                 {
103                         mpeg3_set_cpus(fd, file->cpus);
104                         mpeg3_set_mmx(fd, 0);
106                         asset->audio_data = mpeg3_has_audio(fd);
107                         if(asset->audio_data)
108                         {
109                                 asset->channels = 0;
110                                 for(int i = 0; i < mpeg3_total_astreams(fd); i++)
111                                 {
112                                         asset->channels += mpeg3_audio_channels(fd, i);
113                                 }
114                                 if(!asset->sample_rate)
115                                         asset->sample_rate = mpeg3_sample_rate(fd, 0);
116                                 asset->audio_length = mpeg3_audio_samples(fd, 0); 
117                         }
119                         asset->video_data = mpeg3_has_video(fd);
120                         if(asset->video_data)
121                         {
122                                 asset->layers = mpeg3_total_vstreams(fd);
123                                 asset->width = mpeg3_video_width(fd, 0);
124                                 asset->height = mpeg3_video_height(fd, 0);
125                                 asset->interlace_mode = BC_ILACE_MODE_UNDETECTED; // TODO: (to do this, start at hvirtualcvs/libmpeg3/headers.c 
126                                                                                   //        and find out how to decode info from the header)
127                                 asset->video_length = mpeg3_video_frames(fd, 0);
128                                 asset->vmpeg_cmodel = (mpeg3_colormodel(fd, 0) == MPEG3_YUV422P) ? 1 : 0;
129                                 if(!asset->frame_rate)
130                                         asset->frame_rate = mpeg3_frame_rate(fd, 0);
131                         }
132                 }
133         }
134         
135         
136         
137         if(wr && asset->format == FILE_VMPEG)
138         {
139                 char bitrate_string[BCTEXTLEN];
140                 char quant_string[BCTEXTLEN];
141                 char iframe_string[BCTEXTLEN];
143                 sprintf(bitrate_string, "%d", asset->vmpeg_bitrate);
144                 sprintf(quant_string, "%d", asset->vmpeg_quantization);
145                 sprintf(iframe_string, "%d", asset->vmpeg_iframe_distance);
147 // Construct command line
148                 if(!result)
149                 {
150                         append_vcommand_line("mpeg2enc");
153                         if(asset->aspect_ratio > 0)
154                         {
155                                 append_vcommand_line("-a");
156                                 if(EQUIV(asset->aspect_ratio, 1.333))
157                                         append_vcommand_line("2");
158                                 else
159                                 if(EQUIV(asset->aspect_ratio, 1.777))
160                                         append_vcommand_line("3");
161                                 else
162                                 if(EQUIV(asset->aspect_ratio, 2.11))
163                                         append_vcommand_line("4");
164                         }
166                         append_vcommand_line(asset->vmpeg_derivative == 1 ? "-1" : "");
167                         append_vcommand_line(asset->vmpeg_cmodel == 1 ? "-422" : "");
168                         if(asset->vmpeg_fix_bitrate)
169                         {
170                                 append_vcommand_line("-b");
171                                 append_vcommand_line(bitrate_string);
172                         }
173                         else
174                         {
175                                 append_vcommand_line("-q");
176                                 append_vcommand_line(quant_string);
177                         }
178                         append_vcommand_line(!asset->vmpeg_fix_bitrate ? quant_string : "");
179                         append_vcommand_line("-n");
180                         append_vcommand_line(iframe_string);
181                         append_vcommand_line(asset->vmpeg_progressive ? "-p" : "");
182                         append_vcommand_line(asset->vmpeg_denoise ? "-d" : "");
183                         append_vcommand_line(file->cpus <= 1 ? "-u" : "");
184                         append_vcommand_line(asset->vmpeg_seq_codes ? "-g" : "");
185                         append_vcommand_line(asset->path);
187                         video_out = new FileMPEGVideo(this);
188                         video_out->start();
189                 }
190         }
192         if(wr && asset->format == FILE_AMPEG)
193         {
194                 char command_line[BCTEXTLEN];
195                 char encoder_string[BCTEXTLEN];
196                 char argument_string[BCTEXTLEN];
198 //printf("FileMPEG::open_file 1 %d\n", asset->ampeg_derivative);
199                 encoder_string[0] = 0;
201                 if(asset->ampeg_derivative == 2)
202                 {
203                         char string[BCTEXTLEN];
204                         append_acommand_line("toolame");
205                         append_acommand_line("-m");
206                         append_acommand_line((asset->channels >= 2) ? "j" : "m");
207                         sprintf(string, "%f", (float)asset->sample_rate / 1000);
208                         append_acommand_line("-s");
209                         append_acommand_line(string);
210                         sprintf(string, "%d", asset->ampeg_bitrate);
211                         append_acommand_line("-b");
212                         append_acommand_line(string);
213                         append_acommand_line("-");
214                         append_acommand_line(asset->path);
216                         audio_out = new FileMPEGAudio(this);
217                         audio_out->start();
218                 }
219                 else
220                 if(asset->ampeg_derivative == 3)
221                 {
222                         lame_global = lame_init();
223                         lame_set_brate(lame_global, asset->ampeg_bitrate / 1000);
224                         lame_set_quality(lame_global, 0);
225                         lame_set_in_samplerate(lame_global, 
226                                 asset->sample_rate);
227                         if((result = lame_init_params(lame_global)) < 0)
228                         {
229                                 printf(_("encode: lame_init_params returned %d\n"), result);
230                                 lame_close(lame_global);
231                                 lame_global = 0;
232                         }
233                         else
234                         if(!(lame_fd = fopen(asset->path, "w")))
235                         {
236                                 perror("FileMPEG::open_file");
237                                 lame_close(lame_global);
238                                 lame_global = 0;
239                         }
240                 }
241                 else
242                 {
243                         printf("FileMPEG::open_file: ampeg_derivative=%d\n", asset->ampeg_derivative);
244                         result = 1;
245                 }
246         }
248 //asset->dump();
249 //printf("FileMPEG::open_file 100\n");
250         return result;
253 void FileMPEG::append_vcommand_line(const char *string)
255         if(string[0])
256         {
257                 char *argv = strdup(string);
258                 vcommand_line.append(argv);
259         }
262 void FileMPEG::append_acommand_line(const char *string)
264         if(string[0])
265         {
266                 char *argv = strdup(string);
267                 acommand_line.append(argv);
268         }
272 int FileMPEG::close_file()
274 //printf("FileMPEG::close_file 1\n");
275         if(fd)
276         {
277                 mpeg3_close(fd);
278         }
280         if(video_out)
281         {
282 // End of sequence signal
283                 mpeg2enc_set_input_buffers(1, 0, 0, 0);
284                 delete video_out;
285                 video_out = 0;
286         }
288         vcommand_line.remove_all_objects();
289         acommand_line.remove_all_objects();
291         if(audio_out)
292         {
293                 toolame_send_buffer(0, 0);
294                 delete audio_out;
295                 audio_out = 0;
296         }
298         if(lame_global)
299                 lame_close(lame_global);
301         if(temp_frame) delete temp_frame;
302         if(toolame_temp) delete [] toolame_temp;
304         if(lame_temp[0]) delete [] lame_temp[0];
305         if(lame_temp[1]) delete [] lame_temp[1];
306         if(lame_output) delete [] lame_output;
307         if(lame_fd) fclose(lame_fd);
309         reset_parameters();
310         FileBase::close_file();
311 //printf("FileMPEG::close_file 100\n");
312         return 0;
315 int FileMPEG::get_best_colormodel(Asset *asset, int driver)
317 //printf("FileMPEG::get_best_colormodel 1\n");
318         switch(driver)
319         {
320                 case PLAYBACK_X11:
321                         return BC_RGB888;
322                         if(asset->vmpeg_cmodel == 0) return BC_YUV420P;
323                         if(asset->vmpeg_cmodel == 1) return BC_YUV422P;
324                         break;
325                 case PLAYBACK_X11_XV:
326                         if(asset->vmpeg_cmodel == 0) return BC_YUV420P;
327                         if(asset->vmpeg_cmodel == 1) return BC_YUV422P;
328                         break;
329                 case PLAYBACK_LML:
330                 case PLAYBACK_BUZ:
331                         return BC_YUV422P;
332                         break;
333                 case PLAYBACK_DV1394:
334                 case PLAYBACK_FIREWIRE:
335                         return BC_YUV422P;
336                         break;
337                 case VIDEO4LINUX:
338                 case VIDEO4LINUX2:
339                         if(asset->vmpeg_cmodel == 0) return BC_YUV420P;
340                         if(asset->vmpeg_cmodel == 1) return BC_YUV422P;
341                         break;
342                 case CAPTURE_BUZ:
343                 case CAPTURE_LML:
344                         return BC_YUV422;
345                         break;
346                 case CAPTURE_FIREWIRE:
347                         return BC_YUV422P;
348                         break;
349         }
350 //printf("FileMPEG::get_best_colormodel 100\n");
353 int FileMPEG::colormodel_supported(int colormodel)
355         return colormodel;
359 int FileMPEG::can_copy_from(Edit *edit, int64_t position)
361         if(!fd) return 0;
362         return 0;
365 int FileMPEG::set_audio_position(int64_t sample)
367 #if 0
368         if(!fd) return 1;
369         
370         int channel, stream;
371         to_streamchannel(file->current_channel, stream, channel);
373 //printf("FileMPEG::set_audio_position %d %d %d\n", sample, mpeg3_get_sample(fd, stream), last_sample);
374         if(sample != mpeg3_get_sample(fd, stream) &&
375                 sample != last_sample)
376         {
377                 if(sample >= 0 && sample < asset->audio_length)
378                 {
379 //printf("FileMPEG::set_audio_position seeking stream %d\n", sample);
380                         return mpeg3_set_sample(fd, sample, stream);
381                 }
382                 else
383                         return 1;
384         }
385 #endif
386         return 0;
389 int FileMPEG::set_video_position(int64_t x)
391         if(!fd) return 1;
392         if(x >= 0 && x < asset->video_length)
393         {
394                 mpeg3_set_frame(fd, x, file->current_layer);
395         }
396         else
397                 return 1;
401 int FileMPEG::write_samples(double **buffer, int64_t len)
403         int result = 0;
405 //printf("FileMPEG::write_samples 1\n");
406         if(asset->ampeg_derivative == 2)
407         {
408 // Convert to int16
409                 int channels = MIN(asset->channels, 2);
410                 int64_t audio_size = len * channels * 2;
411                 if(toolame_allocation < audio_size)
412                 {
413                         if(toolame_temp) delete [] toolame_temp;
414                         toolame_temp = new unsigned char[audio_size];
415                         toolame_allocation = audio_size;
416                 }
418                 for(int i = 0; i < channels; i++)
419                 {
420                         int16_t *output = ((int16_t*)toolame_temp) + i;
421                         double *input = buffer[i];
422                         for(int j = 0; j < len; j++)
423                         {
424                                 int sample = (int)(*input * 0x7fff);
425                                 *output = (int16_t)(CLIP(sample, -0x8000, 0x7fff));
426                                 output += channels;
427                                 input++;
428                         }
429                 }
430                 result = toolame_send_buffer((char*)toolame_temp, audio_size);
431         }
432         else
433         if(asset->ampeg_derivative == 3)
434         {
435                 int channels = MIN(asset->channels, 2);
436                 int64_t audio_size = len * channels;
437                 if(!lame_global) return 1;
438                 if(!lame_fd) return 1;
439                 if(lame_allocation < audio_size)
440                 {
441                         if(lame_temp[0]) delete [] lame_temp[0];
442                         if(lame_temp[1]) delete [] lame_temp[1];
443                         lame_temp[0] = new float[audio_size];
444                         lame_temp[1] = new float[audio_size];
445                         lame_allocation = audio_size;
446                 }
448                 if(lame_output_allocation < audio_size * 4)
449                 {
450                         if(lame_output) delete [] lame_output;
451                         lame_output_allocation = audio_size * 4;
452                         lame_output = new char[lame_output_allocation];
453                 }
455                 for(int i = 0; i < channels; i++)
456                 {
457                         float *output = lame_temp[i];
458                         double *input = buffer[i];
459                         for(int j = 0; j < len; j++)
460                         {
461                                 *output++ = *input++ * (float)32768;
462                         }
463                 }
465                 result = lame_encode_buffer_float(lame_global,
466                         lame_temp[0],
467                         (channels > 1) ? lame_temp[1] : lame_temp[0],
468                         len,
469                         (unsigned char*)lame_output,
470                         lame_output_allocation);
471                 if(result > 0)
472                 {
473                         char *real_output = lame_output;
474                         int bytes = result;
475                         if(!lame_started)
476                         {
477                                 for(int i = 0; i < bytes; i++)
478                                         if(lame_output[i])
479                                         {
480                                                 real_output = &lame_output[i];
481                                                 lame_started = 1;
482                                                 bytes -= i;
483                                                 break;
484                                         }
485                         }
486                         if(bytes > 0 && lame_started)
487                         {
488                                 result = !fwrite(real_output, 1, bytes, lame_fd);
489                                 if(result)
490                                         perror("FileMPEG::write_samples");
491                         }
492                         else
493                                 result = 0;
494                 }
495                 else
496                         result = 1;
497         }
499         return result;
502 int FileMPEG::write_frames(VFrame ***frames, int len)
504         int result = 0;
506         if(video_out)
507         {
508                 int temp_w = (int)((asset->width + 15) / 16) * 16;
509                 int temp_h;
510                 int output_cmodel = 
511                         (asset->vmpeg_cmodel == 0) ? BC_YUV420P : BC_YUV422P;
512                 
513                 
514 // Height depends on progressiveness
515                 if(asset->vmpeg_progressive || asset->vmpeg_derivative == 1)
516                         temp_h = (int)((asset->height + 15) / 16) * 16;
517                 else
518                         temp_h = (int)((asset->height + 31) / 32) * 32;
520 //printf("FileMPEG::write_frames 1\n");
521                 
522 // Only 1 layer is supported in MPEG output
523                 for(int i = 0; i < 1; i++)
524                 {
525                         for(int j = 0; j < len; j++)
526                         {
527                                 VFrame *frame = frames[i][j];
528                                 
529                                 
530                                 
531                                 if(frame->get_w() == temp_w &&
532                                         frame->get_h() == temp_h &&
533                                         frame->get_color_model() == output_cmodel)
534                                 {
535                                         mpeg2enc_set_input_buffers(0, 
536                                                 (char*)frame->get_y(),
537                                                 (char*)frame->get_u(),
538                                                 (char*)frame->get_v());
539                                 }
540                                 else
541                                 {
542 //printf("FileMPEG::write_frames 2\n");
543                                         if(temp_frame &&
544                                                 (temp_frame->get_w() != temp_w ||
545                                                 temp_frame->get_h() != temp_h ||
546                                                 temp_frame->get_color_model() || output_cmodel))
547                                         {
548                                                 delete temp_frame;
549                                                 temp_frame = 0;
550                                         }
551 //printf("FileMPEG::write_frames 3\n");
554                                         if(!temp_frame)
555                                         {
556                                                 temp_frame = new VFrame(0, 
557                                                         temp_w, 
558                                                         temp_h, 
559                                                         output_cmodel);
560                                         }
562                                         cmodel_transfer(temp_frame->get_rows(), 
563                                                 frame->get_rows(),
564                                                 temp_frame->get_y(),
565                                                 temp_frame->get_u(),
566                                                 temp_frame->get_v(),
567                                                 frame->get_y(),
568                                                 frame->get_u(),
569                                                 frame->get_v(),
570                                                 0,
571                                                 0,
572                                                 asset->width,
573                                                 asset->height,
574                                                 0,
575                                                 0,
576                                                 asset->width,
577                                                 asset->height,
578                                                 frame->get_color_model(), 
579                                                 temp_frame->get_color_model(),
580                                                 0, 
581                                                 frame->get_w(),
582                                                 temp_w);
584                                         mpeg2enc_set_input_buffers(0, 
585                                                 (char*)temp_frame->get_y(),
586                                                 (char*)temp_frame->get_u(),
587                                                 (char*)temp_frame->get_v());
588                                 }
589                         }
590                 }
591         }
593 //printf("FileMPEG::write_frames 100\n");
596         return result;
599 int FileMPEG::read_frame(VFrame *frame)
601         if(!fd) return 1;
602         int result = 0;
603         int src_cmodel;
605 //printf("FileMPEG::read_frame 1\n");
606         if(mpeg3_colormodel(fd, 0) == MPEG3_YUV420P)
607                 src_cmodel = BC_YUV420P;
608         else
609         if(mpeg3_colormodel(fd, 0) == MPEG3_YUV422P)
610                 src_cmodel = BC_YUV422P;
612 //printf("FileMPEG::read_frame 1 %p %d\n", frame, frame->get_color_model());
613         switch(frame->get_color_model())
614         {
615                 case MPEG3_RGB565:
616                 case MPEG3_BGR888:
617                 case MPEG3_BGRA8888:
618                 case MPEG3_RGB888:
619                 case MPEG3_RGBA8888:
620                 case MPEG3_RGBA16161616:
621                         mpeg3_read_frame(fd, 
622                                         frame->get_rows(), /* Array of pointers to the start of each output row */
623                                         0,                    /* Location in input frame to take picture */
624                                         0, 
625                                         asset->width, 
626                                         asset->height, 
627                                         asset->width,                   /* Dimensions of output_rows */
628                                         asset->height, 
629                                         frame->get_color_model(),             /* One of the color model #defines */
630                                         file->current_layer);
631                         break;
633 // Use Temp
634                 default:
635 // Read these directly
636                         if(frame->get_color_model() == src_cmodel)
637                         {
638                                 mpeg3_read_yuvframe(fd,
639                                         (char*)frame->get_y(),
640                                         (char*)frame->get_u(),
641                                         (char*)frame->get_v(),
642                                         0,
643                                         0,
644                                         asset->width,
645                                         asset->height,
646                                         file->current_layer);
648 // Test composite something
649 // static VFrame *test_frame = 0;
650 // if(!test_frame)
651 // {
652 // FILE *test_fd = 0;
653 // mjpeg_t *test_mjpeg = 0;
654 // test_frame = new VFrame(0, 1920, 1080, BC_YUV420P);
655 // test_mjpeg = mjpeg_new(1920, 1080, 1);
656 // test_fd = fopen("/mov/test.jpg", "r");
657 // fseek(test_fd, 0, SEEK_END);
658 // int test_size = ftell(test_fd);
659 // fseek(test_fd, 0, SEEK_SET);
660 // unsigned char *test_buffer = new unsigned char[test_size];
661 // fread(test_buffer, test_size, 1, test_fd);
662 // mjpeg_decompress(test_mjpeg, 
663 // test_buffer, 
664 // test_size, 
665 // 0,
666 // 0,
667 // test_frame->get_y(),
668 // test_frame->get_u(),
669 // test_frame->get_v(),
670 // BC_YUV420P,
671 // 1);
672 // }
673 // int test_bytes = 1920 * 1080;
674 // unsigned char *output_byte = frame->get_data();
675 // unsigned char *input_byte = test_frame->get_data();
676 // for(int i = 0; i < test_bytes; i++)
677 // {
678 // *output_byte = (*input_byte * 0x80 + *output_byte * 0x80) >> 8;
679 // output_byte++;
680 // input_byte++;
681 // }
682 // test_bytes /= 2;
683 // for(int i = 0; i < test_bytes / 2; i++)
684 // {
685 // *output_byte = (*input_byte * 0x80 + *output_byte * 0x80) >> 8;
686 // output_byte++;
687 // input_byte++;
688 // *output_byte = (*input_byte * 0x80 + *output_byte * 0x80) >> 8;
689 // output_byte++;
690 // input_byte++;
691 // }
692                         }
693                         else
694 // Process through temp frame
695                         {
696                                 char *y, *u, *v;
697                                 mpeg3_read_yuvframe_ptr(fd,
698                                         &y,
699                                         &u,
700                                         &v,
701                                         file->current_layer);
702                                 if(y && u && v)
703                                 {
704                                         cmodel_transfer(frame->get_rows(), 
705                                                 0,
706                                                 frame->get_y(),
707                                                 frame->get_u(),
708                                                 frame->get_v(),
709                                                 (unsigned char*)y,
710                                                 (unsigned char*)u,
711                                                 (unsigned char*)v,
712                                                 0,
713                                                 0,
714                                                 asset->width,
715                                                 asset->height,
716                                                 0,
717                                                 0,
718                                                 asset->width,
719                                                 asset->height,
720                                                 src_cmodel, 
721                                                 frame->get_color_model(),
722                                                 0, 
723                                                 asset->width,
724                                                 frame->get_w());
725                                 }
726                         }
727 //printf("FileMPEG::read_frame 2\n");
728                         break;
729         }
730 //for(int i = 0; i < frame->get_w() * 3 * 20; i++) 
731 //      ((u_int16_t*)frame->get_rows()[0])[i] = 0xffff;
732 //printf("FileMPEG::read_frame 100\n");
733         return result;
736 void FileMPEG::to_streamchannel(int channel, int &stream_out, int &channel_out)
738         for(stream_out = 0, channel_out = file->current_channel; 
739                 stream_out < mpeg3_total_astreams(fd) && 
740                         channel_out >= mpeg3_audio_channels(fd, stream_out);
741                 channel_out -= mpeg3_audio_channels(fd, stream_out), stream_out++)
742         ;
745 int FileMPEG::read_samples(double *buffer, int64_t len)
747         if(!fd) return 0;
749 // This is directed to a FileMPEGBuffer
750         float *temp_float = new float[len];
751 // Translate pure channel to a stream and a channel in the mpeg stream
752         int stream, channel;
753         to_streamchannel(file->current_channel, stream, channel);
754         
755         
756         
757 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
759         mpeg3_set_sample(fd, 
760                 file->current_sample,
761                 stream);
762         mpeg3_read_audio(fd, 
763                 temp_float,      /* Pointer to pre-allocated buffer of floats */
764                 0,      /* Pointer to pre-allocated buffer of int16's */
765                 channel,          /* Channel to decode */
766                 len,         /* Number of samples to decode */
767                 stream);          /* Stream containing the channel */
770 //      last_sample = file->current_sample;
771         for(int i = 0; i < len; i++) buffer[i] = temp_float[i];
773         delete [] temp_float;
774 //printf("FileMPEG::read_samples 100\n");
775         return 0;
778 int FileMPEG::prefer_samples_float()
780         return 1;
783 int FileMPEG::read_samples_float(float *buffer, int64_t len)
785         if(!fd) return 0;
787 // Translate pure channel to a stream and a channel in the mpeg stream
788         int stream, channel;
789         to_streamchannel(file->current_channel, stream, channel);
790         
791         
792 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
794         mpeg3_set_sample(fd, 
795                 file->current_sample,
796                 stream);
797         mpeg3_read_audio(fd, 
798                 buffer,         /* Pointer to pre-allocated buffer of floats */
799                 0,              /* Pointer to pre-allocated buffer of int16's */
800                 channel,          /* Channel to decode */
801                 len,         /* Number of samples to decode */
802                 stream);          /* Stream containing the channel */
805 //      last_sample = file->current_sample;
807 //printf("FileMPEG::read_samples 100\n");
808         return 0;
813 char* FileMPEG::strtocompression(char *string)
815         return "";
818 char* FileMPEG::compressiontostr(char *string)
820         return "";
829 FileMPEGVideo::FileMPEGVideo(FileMPEG *file)
830  : Thread(1, 0, 0)
832         this->file = file;
833         mpeg2enc_init_buffers();
834         mpeg2enc_set_w(file->asset->width);
835         mpeg2enc_set_h(file->asset->height);
836         mpeg2enc_set_rate(file->asset->frame_rate);
839 FileMPEGVideo::~FileMPEGVideo()
841         Thread::join();
844 void FileMPEGVideo::run()
846 printf("FileMPEGVideo::run ");
847 for(int i = 0; i < file->vcommand_line.total; i++)
848         printf("%s ", file->vcommand_line.values[i]);
849 printf("\n");
850         mpeg2enc(file->vcommand_line.total, file->vcommand_line.values);
860 FileMPEGAudio::FileMPEGAudio(FileMPEG *file)
861  : Thread(1, 0, 0)
863         this->file = file;
864         toolame_init_buffers();
867 FileMPEGAudio::~FileMPEGAudio()
869         Thread::join();
872 void FileMPEGAudio::run()
874         file->toolame_result = toolame(file->acommand_line.total, file->acommand_line.values);
884 MPEGConfigAudio::MPEGConfigAudio(BC_WindowBase *parent_window, Asset *asset)
885  : BC_Window(PROGRAM_NAME ": Audio Compression",
886         parent_window->get_abs_cursor_x(1),
887         parent_window->get_abs_cursor_y(1),
888         310,
889         120,
890         -1,
891         -1,
892         0,
893         0,
894         1)
896         this->parent_window = parent_window;
897         this->asset = asset;
900 MPEGConfigAudio::~MPEGConfigAudio()
904 int MPEGConfigAudio::create_objects()
906         int x = 10, y = 10;
907         int x1 = 150;
908         MPEGLayer *layer;
910         add_tool(new BC_Title(x, y, _("Layer:")));
911         add_tool(layer = new MPEGLayer(x1, y, this));
912         layer->create_objects();
914         y += 30;
915         add_tool(new BC_Title(x, y, _("Kbits per second:")));
916         add_tool(bitrate = new MPEGABitrate(x1, y, this));
917         bitrate->create_objects();
918         
919         
920         add_subwindow(new BC_OKButton(this));
921         show_window();
922         flush();
923         return 0;
926 int MPEGConfigAudio::close_event()
928         set_done(0);
929         return 1;
938 MPEGLayer::MPEGLayer(int x, int y, MPEGConfigAudio *gui)
939  : BC_PopupMenu(x, y, 150, layer_to_string(gui->asset->ampeg_derivative))
941         this->gui = gui;
944 void MPEGLayer::create_objects()
946         add_item(new BC_MenuItem(layer_to_string(2)));
947         add_item(new BC_MenuItem(layer_to_string(3)));
950 int MPEGLayer::handle_event()
952         gui->asset->ampeg_derivative = string_to_layer(get_text());
953         gui->bitrate->set_layer(gui->asset->ampeg_derivative);
954         return 1;
957 int MPEGLayer::string_to_layer(char *string)
959         if(!strcasecmp(layer_to_string(2), string))
960                 return 2;
961         if(!strcasecmp(layer_to_string(3), string))
962                 return 3;
964         return 2;
967 char* MPEGLayer::layer_to_string(int layer)
969         switch(layer)
970         {
971                 case 2:
972                         return _("II");
973                         break;
974                 
975                 case 3:
976                         return _("III");
977                         break;
978                         
979                 default:
980                         return _("II");
981                         break;
982         }
991 MPEGABitrate::MPEGABitrate(int x, int y, MPEGConfigAudio *gui)
992  : BC_PopupMenu(x, 
993         y, 
994         150, 
995         bitrate_to_string(gui->string, gui->asset->ampeg_bitrate))
997         this->gui = gui;
1000 void MPEGABitrate::create_objects()
1002         set_layer(gui->asset->ampeg_derivative);
1005 void MPEGABitrate::set_layer(int layer)
1007         while(total_items())
1008         {
1009                 remove_item(0);
1010         }
1012         if(layer == 2)
1013         {
1014                 add_item(new BC_MenuItem("160"));
1015                 add_item(new BC_MenuItem("192"));
1016                 add_item(new BC_MenuItem("224"));
1017                 add_item(new BC_MenuItem("256"));
1018                 add_item(new BC_MenuItem("320"));
1019                 add_item(new BC_MenuItem("384"));
1020         }
1021         else
1022         {
1023                 add_item(new BC_MenuItem("8"));
1024                 add_item(new BC_MenuItem("16"));
1025                 add_item(new BC_MenuItem("24"));
1026                 add_item(new BC_MenuItem("32"));
1027                 add_item(new BC_MenuItem("40"));
1028                 add_item(new BC_MenuItem("48"));
1029                 add_item(new BC_MenuItem("56"));
1030                 add_item(new BC_MenuItem("64"));
1031                 add_item(new BC_MenuItem("80"));
1032                 add_item(new BC_MenuItem("96"));
1033                 add_item(new BC_MenuItem("112"));
1034                 add_item(new BC_MenuItem("128"));
1035                 add_item(new BC_MenuItem("144"));
1036                 add_item(new BC_MenuItem("160"));
1037                 add_item(new BC_MenuItem("192"));
1038                 add_item(new BC_MenuItem("224"));
1039                 add_item(new BC_MenuItem("256"));
1040                 add_item(new BC_MenuItem("320"));
1041         }
1044 int MPEGABitrate::handle_event()
1046         gui->asset->ampeg_bitrate = string_to_bitrate(get_text());
1047         return 1;
1050 int MPEGABitrate::string_to_bitrate(char *string)
1052         return atol(string);
1056 char* MPEGABitrate::bitrate_to_string(char *string, int bitrate)
1058         sprintf(string, "%d", bitrate);
1059         return string;
1070 MPEGConfigVideo::MPEGConfigVideo(BC_WindowBase *parent_window, 
1071         Asset *asset)
1072  : BC_Window(PROGRAM_NAME ": Video Compression",
1073         parent_window->get_abs_cursor_x(1),
1074         parent_window->get_abs_cursor_y(1),
1075         500,
1076         300,
1077         -1,
1078         -1,
1079         0,
1080         0,
1081         1)
1083         this->parent_window = parent_window;
1084         this->asset = asset;
1087 MPEGConfigVideo::~MPEGConfigVideo()
1091 int MPEGConfigVideo::create_objects()
1093         int x = 10, y = 10;
1094         int x1 = x + 150;
1095         int x2 = x + 300;
1096         MPEGDerivative *derivative;
1097         MPEGColorModel *cmodel;
1099         add_subwindow(new BC_Title(x, y + 5, _("Derivative:")));
1100         add_subwindow(derivative = new MPEGDerivative(x1, y, this));
1101         derivative->create_objects();
1102         y += 30;
1104         add_subwindow(new BC_Title(x, y + 5, _("Bitrate:")));
1105         add_subwindow(new MPEGBitrate(x1, y, this));
1106         add_subwindow(fixed_bitrate = new MPEGFixedBitrate(x2, y, this));
1107         y += 30;
1109         add_subwindow(new BC_Title(x, y, _("Quantization:")));
1110         MPEGQuant *quant = new MPEGQuant(x1, y, this);
1111         quant->create_objects();
1112         add_subwindow(fixed_quant = new MPEGFixedQuant(x2, y, this));
1113         y += 30;
1115         add_subwindow(new BC_Title(x, y, _("I frame distance:")));
1116         MPEGIFrameDistance *iframe_distance = 
1117                 new MPEGIFrameDistance(x1, y, this);
1118         iframe_distance->create_objects();
1119         y += 30;
1121         add_subwindow(new BC_Title(x, y, _("Color model:")));
1122         add_subwindow(cmodel = new MPEGColorModel(x1, y, this));
1123         cmodel->create_objects();
1124         y += 30;
1125         
1126 //      add_subwindow(new BC_Title(x, y, _("P frame distance:")));
1127 //      y += 30;
1130         add_subwindow(new BC_CheckBox(x, y, &asset->vmpeg_progressive, _("Progressive frames")));
1131         y += 30;
1132         add_subwindow(new BC_CheckBox(x, y, &asset->vmpeg_denoise, _("Denoise")));
1133         y += 30;
1134         add_subwindow(new BC_CheckBox(x, y, &asset->vmpeg_seq_codes, _("Sequence start codes in every GOP")));
1136         add_subwindow(new BC_OKButton(this));
1137         show_window();
1138         flush();
1139         return 0;
1142 int MPEGConfigVideo::close_event()
1144         set_done(0);
1145         return 1;
1150 MPEGDerivative::MPEGDerivative(int x, int y, MPEGConfigVideo *gui)
1151  : BC_PopupMenu(x, y, 150, derivative_to_string(gui->asset->vmpeg_derivative))
1153         this->gui = gui;
1156 void MPEGDerivative::create_objects()
1158         add_item(new BC_MenuItem(derivative_to_string(1)));
1159         add_item(new BC_MenuItem(derivative_to_string(2)));
1162 int MPEGDerivative::handle_event()
1164         gui->asset->vmpeg_derivative = string_to_derivative(get_text());
1165         return 1;
1168 int MPEGDerivative::string_to_derivative(char *string)
1170         if(!strcasecmp(derivative_to_string(1), string))
1171                 return 1;
1172         if(!strcasecmp(derivative_to_string(2), string))
1173                 return 2;
1175         return 1;
1178 char* MPEGDerivative::derivative_to_string(int derivative)
1180         switch(derivative)
1181         {
1182                 case 1:
1183                         return _("MPEG-1");
1184                         break;
1185                 
1186                 case 2:
1187                         return _("MPEG-2");
1188                         break;
1189                         
1190                 default:
1191                         return _("MPEG-1");
1192                         break;
1193         }
1199 MPEGBitrate::MPEGBitrate(int x, int y, MPEGConfigVideo *gui)
1200  : BC_TextBox(x, y, 100, 1, gui->asset->vmpeg_bitrate)
1202         this->gui = gui;
1206 int MPEGBitrate::handle_event()
1208         gui->asset->vmpeg_bitrate = atol(get_text());
1209         return 1;
1216 MPEGQuant::MPEGQuant(int x, int y, MPEGConfigVideo *gui)
1217  : BC_TumbleTextBox(gui, 
1218         (int64_t)gui->asset->vmpeg_quantization, 
1219         (int64_t)1,
1220         (int64_t)100,
1221         x, 
1222         y,
1223         100)
1225         this->gui = gui;
1228 int MPEGQuant::handle_event()
1230         gui->asset->vmpeg_quantization = atol(get_text());
1231         return 1;
1234 MPEGFixedBitrate::MPEGFixedBitrate(int x, int y, MPEGConfigVideo *gui)
1235  : BC_Radial(x, y, gui->asset->vmpeg_fix_bitrate, _("Fixed bitrate"))
1237         this->gui = gui;
1240 int MPEGFixedBitrate::handle_event()
1242         update(1);
1243         gui->asset->vmpeg_fix_bitrate = 1;
1244         gui->fixed_quant->update(0);
1245         return 1;
1248 MPEGFixedQuant::MPEGFixedQuant(int x, int y, MPEGConfigVideo *gui)
1249  : BC_Radial(x, y, !gui->asset->vmpeg_fix_bitrate, _("Fixed quantization"))
1251         this->gui = gui;
1254 int MPEGFixedQuant::handle_event()
1256         update(1);
1257         gui->asset->vmpeg_fix_bitrate = 0;
1258         gui->fixed_bitrate->update(0);
1259         return 1;
1262 MPEGIFrameDistance::MPEGIFrameDistance(int x, int y, MPEGConfigVideo *gui)
1263  : BC_TumbleTextBox(gui, 
1264         (int64_t)gui->asset->vmpeg_iframe_distance, 
1265         (int64_t)1,
1266         (int64_t)100,
1267         x, 
1268         y,
1269         50)
1271         this->gui = gui;
1274 int MPEGIFrameDistance::handle_event()
1276         gui->asset->vmpeg_iframe_distance = atol(get_text());
1277         return 1;
1281 MPEGColorModel::MPEGColorModel(int x, int y, MPEGConfigVideo *gui)
1282  : BC_PopupMenu(x, y, 150, cmodel_to_string(gui->asset->vmpeg_cmodel))
1284         this->gui = gui;
1287 void MPEGColorModel::create_objects()
1289         add_item(new BC_MenuItem(cmodel_to_string(0)));
1290         add_item(new BC_MenuItem(cmodel_to_string(1)));
1293 int MPEGColorModel::handle_event()
1295         gui->asset->vmpeg_cmodel = string_to_cmodel(get_text());
1296         return 1;
1299 int MPEGColorModel::string_to_cmodel(char *string)
1301         if(!strcasecmp(cmodel_to_string(0), string))
1302                 return 0;
1303         if(!strcasecmp(cmodel_to_string(1), string))
1304                 return 1;
1306         return 1;
1309 char* MPEGColorModel::cmodel_to_string(int cmodel)
1311         switch(cmodel)
1312         {
1313                 case 0:
1314                         return _("YUV 4:2:0");
1315                         break;
1316                 
1317                 case 1:
1318                         return _("YUV 4:2:2");
1319                         break;
1320                         
1321                 default:
1322                         return _("YUV 4:2:0");
1323                         break;
1324         }