Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

filempeg.C

Go to the documentation of this file.
00001 #include "asset.h"
00002 #include "bcprogressbox.h"
00003 #include "bcsignals.h"
00004 #include "bitspopup.h"
00005 #include "byteorder.h"
00006 #include "clip.h"
00007 #include "condition.h"
00008 #include "edit.h"
00009 #include "file.h"
00010 #include "filempeg.h"
00011 #include "filesystem.h"
00012 #include "guicast.h"
00013 #include "indexfile.h"
00014 #include "interlacemodes.h"
00015 #include "language.h"
00016 #include "mwindow.inc"
00017 #include "preferences.h"
00018 #include "vframe.h"
00019 #include "videodevice.inc"
00020 
00021 #include <stdio.h>
00022 #include <string.h>
00023 #include <unistd.h>
00024 
00025 #define MPEG_YUV420 0
00026 #define MPEG_YUV422 1
00027 
00028 
00029 #define MJPEG_EXE PLUGIN_DIR "/mpeg2enc.plugin"
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 // M JPEG dependancies
00038 static double frame_rate_codes[] = 
00039 {
00040         0,
00041         24000.0/1001.0,
00042         24.0,
00043         25.0,
00044         30000.0/1001.0,
00045         30.0,
00046         50.0,
00047         60000.0/1001.0,
00048         60.0
00049 };
00050 
00051 static double aspect_ratio_codes[] =
00052 {
00053         0,
00054         1.0,
00055         1.333,
00056         1.777,
00057         2.11
00058 };
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 FileMPEG::FileMPEG(Asset *asset, File *file)
00068  : FileBase(asset, file)
00069 {
00070         reset_parameters();
00071 // May also be VMPEG or AMPEG if write status.
00072         if(asset->format == FILE_UNKNOWN) asset->format = FILE_MPEG;
00073         asset->byte_order = 0;
00074         next_frame_lock = new Condition(0, "FileMPEG::next_frame_lock");
00075         next_frame_done = new Condition(0, "FileMPEG::next_frame_done");
00076 }
00077 
00078 FileMPEG::~FileMPEG()
00079 {
00080         close_file();
00081         delete next_frame_lock;
00082         delete next_frame_done;
00083 }
00084 
00085 void FileMPEG::get_parameters(BC_WindowBase *parent_window, 
00086         Asset *asset, 
00087         BC_WindowBase* &format_window,
00088         int audio_options,
00089         int video_options)
00090 {
00091         if(audio_options && asset->format == FILE_AMPEG)
00092         {
00093                 MPEGConfigAudio *window = new MPEGConfigAudio(parent_window, asset);
00094                 format_window = window;
00095                 window->create_objects();
00096                 window->run_window();
00097                 delete window;
00098         }
00099         else
00100         if(video_options && asset->format == FILE_VMPEG)
00101         {
00102                 MPEGConfigVideo *window = new MPEGConfigVideo(parent_window, asset);
00103                 format_window = window;
00104                 window->create_objects();
00105                 window->run_window();
00106                 delete window;
00107         }
00108 }
00109 
00110 int FileMPEG::check_sig(Asset *asset)
00111 {
00112         return mpeg3_check_sig(asset->path);
00113 }
00114 
00115 int FileMPEG::reset_parameters_derived()
00116 {
00117         wrote_header = 0;
00118         mjpeg_out = 0;
00119         mjpeg_eof = 0;
00120         mjpeg_error = 0;
00121 
00122 
00123 
00124         fd = 0;
00125         video_out = 0;
00126         audio_out = 0;
00127         prev_track = 0;
00128         temp_frame = 0;
00129         toolame_temp = 0;
00130         toolame_allocation = 0;
00131         toolame_result = 0;
00132         lame_temp[0] = 0;
00133         lame_temp[1] = 0;
00134         lame_allocation = 0;
00135         lame_global = 0;
00136         lame_output = 0;
00137         lame_output_allocation = 0;
00138         lame_fd = 0;
00139         lame_started = 0;
00140 }
00141 
00142 
00143 // Just create the Quicktime objects since this routine is also called
00144 // for reopening.
00145 int FileMPEG::open_file(int rd, int wr)
00146 {
00147         int result = 0;
00148         this->rd = rd;
00149         this->wr = wr;
00150 
00151         if(rd)
00152         {
00153                 if(!(fd = mpeg3_open(asset->path)))
00154                 {
00155                         printf("FileMPEG::open_file %s\n", asset->path);
00156                         result = 1;
00157                 }
00158                 else
00159                 {
00160 // Determine if the file needs a table of contents and create one if needed.
00161                         if(!mpeg3_has_toc(fd))
00162                         {
00163 // If it has video it must be scanned since video has keyframes.
00164                                 if(mpeg3_total_vstreams(fd))
00165                                 {
00166                                         if(create_index()) return 1;
00167                                 }
00168                         }
00169 
00170                         mpeg3_set_cpus(fd, file->cpus);
00171 
00172                         asset->audio_data = mpeg3_has_audio(fd);
00173                         if(asset->audio_data)
00174                         {
00175                                 asset->channels = 0;
00176                                 for(int i = 0; i < mpeg3_total_astreams(fd); i++)
00177                                 {
00178                                         asset->channels += mpeg3_audio_channels(fd, i);
00179                                 }
00180                                 if(!asset->sample_rate)
00181                                         asset->sample_rate = mpeg3_sample_rate(fd, 0);
00182                                 asset->audio_length = mpeg3_audio_samples(fd, 0); 
00183                         }
00184 
00185                         asset->video_data = mpeg3_has_video(fd);
00186                         if(asset->video_data)
00187                         {
00188                                 asset->layers = mpeg3_total_vstreams(fd);
00189                                 asset->width = mpeg3_video_width(fd, 0);
00190                                 asset->height = mpeg3_video_height(fd, 0);
00191                                 asset->interlace_mode = BC_ILACE_MODE_UNDETECTED; // TODO: (to do this, start at hvirtualcvs/libmpeg3/headers.c 
00192                                                                                   //        and find out how to decode info from the header)
00193                                 asset->video_length = mpeg3_video_frames(fd, 0);
00194                                 asset->vmpeg_cmodel = 
00195                                         (mpeg3_colormodel(fd, 0) == MPEG3_YUV422P) ? MPEG_YUV422 : MPEG_YUV420;
00196                                 if(!asset->frame_rate)
00197                                         asset->frame_rate = mpeg3_frame_rate(fd, 0);
00198                         }
00199                 }
00200         }
00201         
00202         
00203         
00204         if(wr && asset->format == FILE_VMPEG)
00205         {
00206 // Heroine Virtual encoder
00207                 if(asset->vmpeg_cmodel == MPEG_YUV422)
00208                 {
00209                         char bitrate_string[BCTEXTLEN];
00210                         char quant_string[BCTEXTLEN];
00211                         char iframe_string[BCTEXTLEN];
00212 
00213                         sprintf(bitrate_string, "%d", asset->vmpeg_bitrate);
00214                         sprintf(quant_string, "%d", asset->vmpeg_quantization);
00215                         sprintf(iframe_string, "%d", asset->vmpeg_iframe_distance);
00216 
00217 // Construct command line
00218                         if(!result)
00219                         {
00220                                 append_vcommand_line("mpeg2enc");
00221 
00222 
00223                                 if(asset->aspect_ratio > 0)
00224                                 {
00225                                         append_vcommand_line("-a");
00226                                         if(EQUIV(asset->aspect_ratio, 1))
00227                                                 append_vcommand_line("1");
00228                                         else
00229                                         if(EQUIV(asset->aspect_ratio, 1.333))
00230                                                 append_vcommand_line("2");
00231                                         else
00232                                         if(EQUIV(asset->aspect_ratio, 1.777))
00233                                                 append_vcommand_line("3");
00234                                         else
00235                                         if(EQUIV(asset->aspect_ratio, 2.11))
00236                                                 append_vcommand_line("4");
00237                                 }
00238 
00239                                 append_vcommand_line(asset->vmpeg_derivative == 1 ? "-1" : "");
00240                                 append_vcommand_line(asset->vmpeg_cmodel == MPEG_YUV422 ? "-422" : "");
00241                                 if(asset->vmpeg_fix_bitrate)
00242                                 {
00243                                         append_vcommand_line("-b");
00244                                         append_vcommand_line(bitrate_string);
00245                                 }
00246                                 else
00247                                 {
00248                                         append_vcommand_line("-q");
00249                                         append_vcommand_line(quant_string);
00250                                 }
00251                                 append_vcommand_line(!asset->vmpeg_fix_bitrate ? quant_string : "");
00252                                 append_vcommand_line("-n");
00253                                 append_vcommand_line(iframe_string);
00254                                 append_vcommand_line(asset->vmpeg_progressive ? "-p" : "");
00255                                 append_vcommand_line(asset->vmpeg_denoise ? "-d" : "");
00256                                 append_vcommand_line(file->cpus <= 1 ? "-u" : "");
00257                                 append_vcommand_line(asset->vmpeg_seq_codes ? "-g" : "");
00258                                 append_vcommand_line(asset->path);
00259 
00260                                 video_out = new FileMPEGVideo(this);
00261                                 video_out->start();
00262                         }
00263                 }
00264                 else
00265 // mjpegtools encoder
00266                 {
00267                         char string[BCTEXTLEN];
00268                         sprintf(mjpeg_command, MJPEG_EXE);
00269 
00270                         if(asset->vmpeg_fix_bitrate)
00271                         {
00272                                 sprintf(string, " -b %d -q %d", asset->vmpeg_bitrate, 0);
00273                         }
00274                         else
00275                         {
00276                                 sprintf(string, " -b %d -q %d", asset->vmpeg_bitrate, asset->vmpeg_quantization);
00277                         }
00278                         strcat(mjpeg_command, string);
00279 
00280 
00281 
00282 
00283 
00284 
00285 // Aspect ratio
00286                         int aspect_ratio_code = -1;
00287                         if(asset->aspect_ratio > 0)
00288                         {
00289                                 for(int i = 0; i < sizeof(aspect_ratio_codes) / sizeof(double); i++)
00290                                 {
00291                                         if(EQUIV(aspect_ratio_codes[i], asset->aspect_ratio))
00292                                         {
00293                                                 aspect_ratio_code = i;
00294                                                 break;
00295                                         }
00296                                 }
00297                         }
00298                         if(aspect_ratio_code < 0)
00299                         {
00300                                 printf("FileMPEG::open_file: Unsupported aspect ratio %f\n", asset->aspect_ratio);
00301                                 aspect_ratio_code = 2;
00302                         }
00303                         sprintf(string, " -a %d", aspect_ratio_code);
00304                         strcat(mjpeg_command, string);
00305 
00306 
00307 
00308 
00309 
00310 
00311 // Frame rate
00312                         int frame_rate_code = -1;
00313                 for(int i = 1; sizeof(frame_rate_codes) / sizeof(double); ++i)
00314                         {
00315                                 if(EQUIV(asset->frame_rate, frame_rate_codes[i]))
00316                                 {
00317                                         frame_rate_code = i;
00318                                         break;
00319                                 }
00320                         }
00321                         if(frame_rate_code < 0)
00322                         {
00323                                 frame_rate_code = 4;
00324                                 printf("FileMPEG::open_file: Unsupported frame rate %f\n", asset->frame_rate);
00325                         }
00326                         sprintf(string, " -F %d", frame_rate_code);
00327                         strcat(mjpeg_command, string);
00328 
00329 
00330 
00331 
00332 
00333                         strcat(mjpeg_command, asset->vmpeg_progressive ? " -I 0" : " -I 1");
00334                         
00335 
00336 
00337                         sprintf(string, " -M %d", file->cpus);
00338                         strcat(mjpeg_command, string);
00339 
00340 
00341                         if(!asset->vmpeg_progressive)
00342                         {
00343                                 strcat(mjpeg_command, asset->vmpeg_field_order ? " -z b" : " -z t");
00344                         }
00345 
00346 
00347                         sprintf(string, " -f %d", asset->vmpeg_preset);
00348                         strcat(mjpeg_command, string);
00349 
00350 
00351                         sprintf(string, " -g %d -G %d", asset->vmpeg_iframe_distance, asset->vmpeg_iframe_distance);
00352                         strcat(mjpeg_command, string);
00353 
00354 
00355                         if(asset->vmpeg_seq_codes) strcat(mjpeg_command, " -s");
00356 
00357 
00358                         sprintf(string, " -R %d", CLAMP(asset->vmpeg_pframe_distance, 0, 2));
00359                         strcat(mjpeg_command, string);
00360 
00361                         sprintf(string, " -o %s", asset->path);
00362                         strcat(mjpeg_command, string);
00363 
00364 
00365 
00366                         printf("FileMPEG::open_file: Running %s\n", mjpeg_command);
00367                         if(!(mjpeg_out = popen(mjpeg_command, "w")))
00368                         {
00369                                 perror("FileMPEG::open_file");
00370                         }
00371 
00372                         video_out = new FileMPEGVideo(this);
00373                         video_out->start();
00374                 }
00375         }
00376 
00377         if(wr && asset->format == FILE_AMPEG)
00378         {
00379                 char command_line[BCTEXTLEN];
00380                 char encoder_string[BCTEXTLEN];
00381                 char argument_string[BCTEXTLEN];
00382 
00383 //printf("FileMPEG::open_file 1 %d\n", asset->ampeg_derivative);
00384                 encoder_string[0] = 0;
00385 
00386                 if(asset->ampeg_derivative == 2)
00387                 {
00388                         char string[BCTEXTLEN];
00389                         append_acommand_line("toolame");
00390                         append_acommand_line("-m");
00391                         append_acommand_line((asset->channels >= 2) ? "j" : "m");
00392                         sprintf(string, "%f", (float)asset->sample_rate / 1000);
00393                         append_acommand_line("-s");
00394                         append_acommand_line(string);
00395                         sprintf(string, "%d", asset->ampeg_bitrate);
00396                         append_acommand_line("-b");
00397                         append_acommand_line(string);
00398                         append_acommand_line("-");
00399                         append_acommand_line(asset->path);
00400 
00401                         audio_out = new FileMPEGAudio(this);
00402                         audio_out->start();
00403                 }
00404                 else
00405                 if(asset->ampeg_derivative == 3)
00406                 {
00407                         lame_global = lame_init();
00408                         lame_set_brate(lame_global, asset->ampeg_bitrate / 1000);
00409                         lame_set_quality(lame_global, 0);
00410                         lame_set_in_samplerate(lame_global, 
00411                                 asset->sample_rate);
00412                         if((result = lame_init_params(lame_global)) < 0)
00413                         {
00414                                 printf(_("encode: lame_init_params returned %d\n"), result);
00415                                 lame_close(lame_global);
00416                                 lame_global = 0;
00417                         }
00418                         else
00419                         if(!(lame_fd = fopen(asset->path, "w")))
00420                         {
00421                                 perror("FileMPEG::open_file");
00422                                 lame_close(lame_global);
00423                                 lame_global = 0;
00424                         }
00425                 }
00426                 else
00427                 {
00428                         printf("FileMPEG::open_file: ampeg_derivative=%d\n", asset->ampeg_derivative);
00429                         result = 1;
00430                 }
00431         }
00432 
00433 //asset->dump();
00434 //printf("FileMPEG::open_file 100\n");
00435         return result;
00436 }
00437 
00438 
00439 
00440 
00441 
00442 
00443 
00444 
00445 int FileMPEG::create_index()
00446 {
00447 // Calculate TOC path
00448         char index_filename[BCTEXTLEN];
00449         char source_filename[BCTEXTLEN];
00450         IndexFile::get_index_filename(source_filename, 
00451                 file->preferences->index_directory, 
00452                 index_filename, 
00453                 asset->path);
00454         char *ptr = strrchr(index_filename, '.');
00455         if(!ptr) return 1;
00456 
00457         sprintf(ptr, ".toc");
00458 
00459 // Test existence of TOC
00460         FILE *test = fopen(index_filename, "r");
00461         if(test)
00462         {
00463 // Reopen with table of contents
00464                 fclose(test);
00465         }
00466         else
00467         {
00468 // Create progress window.
00469 // This gets around the fact that MWindowGUI is locked.
00470                 char progress_title[BCTEXTLEN];
00471                 char string[BCTEXTLEN];
00472                 sprintf(progress_title, "Creating %s\n", index_filename);
00473                 int64_t total_bytes;
00474                 mpeg3_t *index_file = mpeg3_start_toc(asset->path, index_filename, &total_bytes);
00475                 struct timeval new_time;
00476                 struct timeval prev_time;
00477                 struct timeval start_time;
00478                 struct timeval current_time;
00479                 gettimeofday(&prev_time, 0);
00480                 gettimeofday(&start_time, 0);
00481 
00482                 BC_ProgressBox *progress = new BC_ProgressBox(-1, 
00483                         -1, 
00484                         progress_title, 
00485                         total_bytes);
00486                 progress->start();
00487                 int result = 0;
00488                 while(1)
00489                 {
00490                         int64_t bytes_processed;
00491                         mpeg3_do_toc(index_file, &bytes_processed);
00492                         gettimeofday(&new_time, 0);
00493 
00494                         if(new_time.tv_sec - prev_time.tv_sec >= 1)
00495                         {
00496                                 gettimeofday(&current_time, 0);
00497                                 int64_t elapsed_seconds = current_time.tv_sec - start_time.tv_sec;
00498                                 int64_t total_seconds = elapsed_seconds * total_bytes / bytes_processed;
00499                                 int64_t eta = total_seconds - elapsed_seconds;
00500                                 progress->update(bytes_processed, 1);
00501                                 sprintf(string, 
00502                                         "%sETA: %lldm%llds",
00503                                         progress_title,
00504                                         eta / 60,
00505                                         eta % 60);
00506                                 progress->update_title(string, 1);
00507 //                              fprintf(stderr, "ETA: %dm%ds        \r", 
00508 //                                      bytes_processed * 100 / total_bytes,
00509 //                                      eta / 60,
00510 //                                      eta % 60);
00511 //                              fflush(stdout);
00512                                 prev_time = new_time;
00513                         }
00514                         if(bytes_processed >= total_bytes) break;
00515                         if(progress->is_cancelled()) 
00516                         {
00517                                 result = 1;
00518                                 break;
00519                         }
00520                 }
00521 
00522                 mpeg3_stop_toc(index_file);
00523 
00524                 progress->stop_progress();
00525                 delete progress;
00526                 if(result)
00527                 {
00528                         remove(index_filename);
00529                         return 1;
00530                 }
00531         }
00532 
00533 
00534 // Failed
00535 
00536 // Reopen file from index path instead of asset path.
00537         if(fd) mpeg3_close(fd);
00538         if(!(fd = mpeg3_open(index_filename)))
00539         {
00540                 return 1;
00541         }
00542         else
00543                 return 0;
00544 }
00545 
00546 
00547 
00548 
00549 
00550 
00551 void FileMPEG::append_vcommand_line(const char *string)
00552 {
00553         if(string[0])
00554         {
00555                 char *argv = strdup(string);
00556                 vcommand_line.append(argv);
00557         }
00558 }
00559 
00560 void FileMPEG::append_acommand_line(const char *string)
00561 {
00562         if(string[0])
00563         {
00564                 char *argv = strdup(string);
00565                 acommand_line.append(argv);
00566         }
00567 }
00568 
00569 
00570 int FileMPEG::close_file()
00571 {
00572         mjpeg_eof = 1;
00573         next_frame_lock->unlock();
00574 
00575         if(fd)
00576         {
00577                 mpeg3_close(fd);
00578         }
00579 
00580         if(video_out)
00581         {
00582 // End of sequence signal
00583                 if(file->asset->vmpeg_cmodel == MPEG_YUV422)
00584                 {
00585                         mpeg2enc_set_input_buffers(1, 0, 0, 0);
00586                 }
00587                 delete video_out;
00588                 video_out = 0;
00589         }
00590 
00591         vcommand_line.remove_all_objects();
00592         acommand_line.remove_all_objects();
00593 
00594         if(audio_out)
00595         {
00596                 toolame_send_buffer(0, 0);
00597                 delete audio_out;
00598                 audio_out = 0;
00599         }
00600 
00601         if(lame_global)
00602                 lame_close(lame_global);
00603 
00604         if(temp_frame) delete temp_frame;
00605         if(toolame_temp) delete [] toolame_temp;
00606 
00607         if(lame_temp[0]) delete [] lame_temp[0];
00608         if(lame_temp[1]) delete [] lame_temp[1];
00609         if(lame_output) delete [] lame_output;
00610         if(lame_fd) fclose(lame_fd);
00611 
00612         if(mjpeg_out) fclose(mjpeg_out);
00613         reset_parameters();
00614 
00615         FileBase::close_file();
00616         return 0;
00617 }
00618 
00619 int FileMPEG::get_best_colormodel(Asset *asset, int driver)
00620 {
00621 //printf("FileMPEG::get_best_colormodel 1\n");
00622         switch(driver)
00623         {
00624                 case PLAYBACK_X11:
00625                         return BC_RGB888;
00626                         if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
00627                         if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
00628                         break;
00629                 case PLAYBACK_X11_XV:
00630                         if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
00631                         if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
00632                         break;
00633                 case PLAYBACK_LML:
00634                 case PLAYBACK_BUZ:
00635                         return BC_YUV422P;
00636                         break;
00637                 case PLAYBACK_DV1394:
00638                 case PLAYBACK_FIREWIRE:
00639                         return BC_YUV422P;
00640                         break;
00641                 case VIDEO4LINUX:
00642                 case VIDEO4LINUX2:
00643                         if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
00644                         if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
00645                         break;
00646                 case CAPTURE_BUZ:
00647                 case CAPTURE_LML:
00648                         return BC_YUV422;
00649                         break;
00650                 case CAPTURE_FIREWIRE:
00651                 case CAPTURE_IEC61883:
00652                         return BC_YUV422P;
00653                         break;
00654         }
00655 //printf("FileMPEG::get_best_colormodel 100\n");
00656 }
00657 
00658 int FileMPEG::colormodel_supported(int colormodel)
00659 {
00660         return colormodel;
00661 }
00662 
00663 int FileMPEG::get_index(char *index_path)
00664 {
00665         if(!fd) return 1;
00666 
00667 
00668 // Convert the index tables from tracks to channels.
00669         if(mpeg3_index_tracks(fd))
00670         {
00671 // Calculate size of buffer needed for all channels
00672                 int buffer_size = 0;
00673                 for(int i = 0; i < mpeg3_index_tracks(fd); i++)
00674                 {
00675                         buffer_size += mpeg3_index_size(fd, i) *
00676                                 mpeg3_index_channels(fd, i) *
00677                                 2;
00678                 }
00679 
00680                 asset->index_buffer = new float[buffer_size];
00681 
00682 // Size of index buffer in floats
00683                 int current_offset = 0;
00684 // Current asset channel
00685                 int current_channel = 0;
00686                 asset->index_zoom = mpeg3_index_zoom(fd);
00687                 asset->index_offsets = new int64_t[asset->channels];
00688                 asset->index_sizes = new int64_t[asset->channels];
00689                 for(int i = 0; i < mpeg3_index_tracks(fd); i++)
00690                 {
00691                         for(int j = 0; j < mpeg3_index_channels(fd, i); j++)
00692                         {
00693                                 asset->index_offsets[current_channel] = current_offset;
00694                                 asset->index_sizes[current_channel] = mpeg3_index_size(fd, i) * 2;
00695                                 memcpy(asset->index_buffer + current_offset,
00696                                         mpeg3_index_data(fd, i, j),
00697                                         mpeg3_index_size(fd, i) * sizeof(float) * 2);
00698 
00699                                 current_offset += mpeg3_index_size(fd, i) * 2;
00700                                 current_channel++;
00701                         }
00702                 }
00703 
00704                 FileSystem fs;
00705                 asset->index_bytes = fs.get_size(asset->path);
00706 
00707                 asset->write_index(index_path, buffer_size * sizeof(float));
00708                 delete [] asset->index_buffer;
00709 
00710                 return 0;
00711         }
00712 
00713         return 1;
00714 }
00715 
00716 
00717 int FileMPEG::can_copy_from(Edit *edit, int64_t position)
00718 {
00719         if(!fd) return 0;
00720         return 0;
00721 }
00722 
00723 int FileMPEG::set_audio_position(int64_t sample)
00724 {
00725 #if 0
00726         if(!fd) return 1;
00727         
00728         int channel, stream;
00729         to_streamchannel(file->current_channel, stream, channel);
00730 
00731 //printf("FileMPEG::set_audio_position %d %d %d\n", sample, mpeg3_get_sample(fd, stream), last_sample);
00732         if(sample != mpeg3_get_sample(fd, stream) &&
00733                 sample != last_sample)
00734         {
00735                 if(sample >= 0 && sample < asset->audio_length)
00736                 {
00737 //printf("FileMPEG::set_audio_position seeking stream %d\n", sample);
00738                         return mpeg3_set_sample(fd, sample, stream);
00739                 }
00740                 else
00741                         return 1;
00742         }
00743 #endif
00744         return 0;
00745 }
00746 
00747 int FileMPEG::set_video_position(int64_t x)
00748 {
00749         if(!fd) return 1;
00750         if(x >= 0 && x < asset->video_length)
00751         {
00752                 mpeg3_set_frame(fd, x, file->current_layer);
00753         }
00754         else
00755                 return 1;
00756 }
00757 
00758 
00759 int FileMPEG::write_samples(double **buffer, int64_t len)
00760 {
00761         int result = 0;
00762 
00763 //printf("FileMPEG::write_samples 1\n");
00764         if(asset->ampeg_derivative == 2)
00765         {
00766 // Convert to int16
00767                 int channels = MIN(asset->channels, 2);
00768                 int64_t audio_size = len * channels * 2;
00769                 if(toolame_allocation < audio_size)
00770                 {
00771                         if(toolame_temp) delete [] toolame_temp;
00772                         toolame_temp = new unsigned char[audio_size];
00773                         toolame_allocation = audio_size;
00774                 }
00775 
00776                 for(int i = 0; i < channels; i++)
00777                 {
00778                         int16_t *output = ((int16_t*)toolame_temp) + i;
00779                         double *input = buffer[i];
00780                         for(int j = 0; j < len; j++)
00781                         {
00782                                 int sample = (int)(*input * 0x7fff);
00783                                 *output = (int16_t)(CLIP(sample, -0x8000, 0x7fff));
00784                                 output += channels;
00785                                 input++;
00786                         }
00787                 }
00788                 result = toolame_send_buffer((char*)toolame_temp, audio_size);
00789         }
00790         else
00791         if(asset->ampeg_derivative == 3)
00792         {
00793                 int channels = MIN(asset->channels, 2);
00794                 int64_t audio_size = len * channels;
00795                 if(!lame_global) return 1;
00796                 if(!lame_fd) return 1;
00797                 if(lame_allocation < audio_size)
00798                 {
00799                         if(lame_temp[0]) delete [] lame_temp[0];
00800                         if(lame_temp[1]) delete [] lame_temp[1];
00801                         lame_temp[0] = new float[audio_size];
00802                         lame_temp[1] = new float[audio_size];
00803                         lame_allocation = audio_size;
00804                 }
00805 
00806                 if(lame_output_allocation < audio_size * 4)
00807                 {
00808                         if(lame_output) delete [] lame_output;
00809                         lame_output_allocation = audio_size * 4;
00810                         lame_output = new char[lame_output_allocation];
00811                 }
00812 
00813                 for(int i = 0; i < channels; i++)
00814                 {
00815                         float *output = lame_temp[i];
00816                         double *input = buffer[i];
00817                         for(int j = 0; j < len; j++)
00818                         {
00819                                 *output++ = *input++ * (float)32768;
00820                         }
00821                 }
00822 
00823                 result = lame_encode_buffer_float(lame_global,
00824                         lame_temp[0],
00825                         (channels > 1) ? lame_temp[1] : lame_temp[0],
00826                         len,
00827                         (unsigned char*)lame_output,
00828                         lame_output_allocation);
00829                 if(result > 0)
00830                 {
00831                         char *real_output = lame_output;
00832                         int bytes = result;
00833                         if(!lame_started)
00834                         {
00835                                 for(int i = 0; i < bytes; i++)
00836                                         if(lame_output[i])
00837                                         {
00838                                                 real_output = &lame_output[i];
00839                                                 lame_started = 1;
00840                                                 bytes -= i;
00841                                                 break;
00842                                         }
00843                         }
00844                         if(bytes > 0 && lame_started)
00845                         {
00846                                 result = !fwrite(real_output, 1, bytes, lame_fd);
00847                                 if(result)
00848                                         perror("FileMPEG::write_samples");
00849                         }
00850                         else
00851                                 result = 0;
00852                 }
00853                 else
00854                         result = 1;
00855         }
00856 
00857         return result;
00858 }
00859 
00860 int FileMPEG::write_frames(VFrame ***frames, int len)
00861 {
00862         int result = 0;
00863 
00864         if(video_out)
00865         {
00866                 int temp_w = (int)((asset->width + 15) / 16) * 16;
00867                 int temp_h;
00868 
00869 
00870                 int output_cmodel = 
00871                         (asset->vmpeg_cmodel == MPEG_YUV420) ? BC_YUV420P : BC_YUV422P;
00872                 
00873                 
00874 // Height depends on progressiveness
00875                 if(asset->vmpeg_progressive || asset->vmpeg_derivative == 1)
00876                         temp_h = (int)((asset->height + 15) / 16) * 16;
00877                 else
00878                         temp_h = (int)((asset->height + 31) / 32) * 32;
00879 
00880 //printf("FileMPEG::write_frames 1\n");
00881                 
00882 // Only 1 layer is supported in MPEG output
00883                 for(int i = 0; i < 1; i++)
00884                 {
00885                         for(int j = 0; j < len && !result; j++)
00886                         {
00887                                 VFrame *frame = frames[i][j];
00888                                 
00889                                 
00890                                 
00891                                 if(asset->vmpeg_cmodel == MPEG_YUV422)
00892                                 {
00893                                         if(frame->get_w() == temp_w &&
00894                                                 frame->get_h() == temp_h &&
00895                                                 frame->get_color_model() == output_cmodel)
00896                                         {
00897                                                 mpeg2enc_set_input_buffers(0, 
00898                                                         (char*)frame->get_y(),
00899                                                         (char*)frame->get_u(),
00900                                                         (char*)frame->get_v());
00901                                         }
00902                                         else
00903                                         {
00904                                                 if(temp_frame &&
00905                                                         (temp_frame->get_w() != temp_w ||
00906                                                         temp_frame->get_h() != temp_h ||
00907                                                         temp_frame->get_color_model() || output_cmodel))
00908                                                 {
00909                                                         delete temp_frame;
00910                                                         temp_frame = 0;
00911                                                 }
00912 
00913 
00914                                                 if(!temp_frame)
00915                                                 {
00916                                                         temp_frame = new VFrame(0, 
00917                                                                 temp_w, 
00918                                                                 temp_h, 
00919                                                                 output_cmodel);
00920                                                 }
00921 
00922                                                 cmodel_transfer(temp_frame->get_rows(), 
00923                                                         frame->get_rows(),
00924                                                         temp_frame->get_y(),
00925                                                         temp_frame->get_u(),
00926                                                         temp_frame->get_v(),
00927                                                         frame->get_y(),
00928                                                         frame->get_u(),
00929                                                         frame->get_v(),
00930                                                         0,
00931                                                         0,
00932                                                         asset->width,
00933                                                         asset->height,
00934                                                         0,
00935                                                         0,
00936                                                         asset->width,
00937                                                         asset->height,
00938                                                         frame->get_color_model(), 
00939                                                         temp_frame->get_color_model(),
00940                                                         0, 
00941                                                         frame->get_w(),
00942                                                         temp_w);
00943 
00944                                                 mpeg2enc_set_input_buffers(0, 
00945                                                         (char*)temp_frame->get_y(),
00946                                                         (char*)temp_frame->get_u(),
00947                                                         (char*)temp_frame->get_v());
00948                                         }
00949                                 }
00950                                 else
00951                                 {
00952 // MJPEG uses the same dimensions as the input
00953                                         if(frame->get_color_model() == output_cmodel)
00954                                         {
00955                                                 mjpeg_y = frame->get_y();
00956                                                 mjpeg_u = frame->get_u();
00957                                                 mjpeg_v = frame->get_v();
00958                                         }
00959                                         else
00960                                         {
00961                                                 if(!temp_frame)
00962                                                 {
00963                                                         temp_frame = new VFrame(0, 
00964                                                                 asset->width, 
00965                                                                 asset->height, 
00966                                                                 output_cmodel);
00967                                                 }
00968 
00969                                                 cmodel_transfer(temp_frame->get_rows(), 
00970                                                         frame->get_rows(),
00971                                                         temp_frame->get_y(),
00972                                                         temp_frame->get_u(),
00973                                                         temp_frame->get_v(),
00974                                                         frame->get_y(),
00975                                                         frame->get_u(),
00976                                                         frame->get_v(),
00977                                                         0,
00978                                                         0,
00979                                                         asset->width,
00980                                                         asset->height,
00981                                                         0,
00982                                                         0,
00983                                                         asset->width,
00984                                                         asset->height,
00985                                                         frame->get_color_model(), 
00986                                                         temp_frame->get_color_model(),
00987                                                         0, 
00988                                                         frame->get_w(),
00989                                                         temp_w);
00990 
00991                                                 mjpeg_y = temp_frame->get_y();
00992                                                 mjpeg_u = temp_frame->get_u();
00993                                                 mjpeg_v = temp_frame->get_v();
00994                                         }
00995 
00996 
00997 
00998 
00999                                         next_frame_lock->unlock();
01000                                         next_frame_done->lock("FileMPEG::write_frames");
01001                                         if(mjpeg_error) result = 1;
01002                                 }
01003 
01004 
01005 
01006 
01007 
01008                         }
01009                 }
01010         }
01011 
01012 
01013 
01014         return result;
01015 }
01016 
01017 int FileMPEG::read_frame(VFrame *frame)
01018 {
01019         if(!fd) return 1;
01020         int result = 0;
01021         int src_cmodel;
01022 
01023 SET_TRACE
01024         if(mpeg3_colormodel(fd, 0) == MPEG3_YUV420P)
01025                 src_cmodel = BC_YUV420P;
01026         else
01027         if(mpeg3_colormodel(fd, 0) == MPEG3_YUV422P)
01028                 src_cmodel = BC_YUV422P;
01029 
01030 SET_TRACE
01031         switch(frame->get_color_model())
01032         {
01033                 case MPEG3_RGB565:
01034                 case MPEG3_BGR888:
01035                 case MPEG3_BGRA8888:
01036                 case MPEG3_RGB888:
01037                 case MPEG3_RGBA8888:
01038                 case MPEG3_RGBA16161616:
01039                         mpeg3_read_frame(fd, 
01040                                         frame->get_rows(), /* Array of pointers to the start of each output row */
01041                                         0,                    /* Location in input frame to take picture */
01042                                         0, 
01043                                         asset->width, 
01044                                         asset->height, 
01045                                         asset->width,                   /* Dimensions of output_rows */
01046                                         asset->height, 
01047                                         frame->get_color_model(),             /* One of the color model #defines */
01048                                         file->current_layer);
01049                         break;
01050 
01051 // Use Temp
01052                 default:
01053 // Read these directly
01054                         if(frame->get_color_model() == src_cmodel)
01055                         {
01056                                 mpeg3_read_yuvframe(fd,
01057                                         (char*)frame->get_y(),
01058                                         (char*)frame->get_u(),
01059                                         (char*)frame->get_v(),
01060                                         0,
01061                                         0,
01062                                         asset->width,
01063                                         asset->height,
01064                                         file->current_layer);
01065 
01066                         }
01067                         else
01068 // Process through temp frame
01069                         {
01070                                 char *y, *u, *v;
01071                                 mpeg3_read_yuvframe_ptr(fd,
01072                                         &y,
01073                                         &u,
01074                                         &v,
01075                                         file->current_layer);
01076                                 if(y && u && v)
01077                                 {
01078                                         cmodel_transfer(frame->get_rows(), 
01079                                                 0,
01080                                                 frame->get_y(),
01081                                                 frame->get_u(),
01082                                                 frame->get_v(),
01083                                                 (unsigned char*)y,
01084                                                 (unsigned char*)u,
01085                                                 (unsigned char*)v,
01086                                                 0,
01087                                                 0,
01088                                                 asset->width,
01089                                                 asset->height,
01090                                                 0,
01091                                                 0,
01092                                                 asset->width,
01093                                                 asset->height,
01094                                                 src_cmodel, 
01095                                                 frame->get_color_model(),
01096                                                 0, 
01097                                                 asset->width,
01098                                                 frame->get_w());
01099                                 }
01100                         }
01101 SET_TRACE
01102                         break;
01103         }
01104 
01105         return result;
01106 }
01107 
01108 void FileMPEG::to_streamchannel(int channel, int &stream_out, int &channel_out)
01109 {
01110         for(stream_out = 0, channel_out = file->current_channel; 
01111                 stream_out < mpeg3_total_astreams(fd) && 
01112                         channel_out >= mpeg3_audio_channels(fd, stream_out);
01113                 channel_out -= mpeg3_audio_channels(fd, stream_out), stream_out++)
01114         ;
01115 }
01116 
01117 int FileMPEG::read_samples(double *buffer, int64_t len)
01118 {
01119         if(!fd) return 0;
01120 
01121 // This is directed to a FileMPEGBuffer
01122         float *temp_float = new float[len];
01123 // Translate pure channel to a stream and a channel in the mpeg stream
01124         int stream, channel;
01125         to_streamchannel(file->current_channel, stream, channel);
01126         
01127         
01128         
01129 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
01130 
01131         mpeg3_set_sample(fd, 
01132                 file->current_sample,
01133                 stream);
01134         mpeg3_read_audio(fd, 
01135                 temp_float,      /* Pointer to pre-allocated buffer of floats */
01136                 0,      /* Pointer to pre-allocated buffer of int16's */
01137                 channel,          /* Channel to decode */
01138                 len,         /* Number of samples to decode */
01139                 stream);          /* Stream containing the channel */
01140 
01141 
01142 //      last_sample = file->current_sample;
01143         for(int i = 0; i < len; i++) buffer[i] = temp_float[i];
01144 
01145         delete [] temp_float;
01146         return 0;
01147 }
01148 
01149 int FileMPEG::prefer_samples_float()
01150 {
01151         return 1;
01152 }
01153 
01154 int FileMPEG::read_samples_float(float *buffer, int64_t len)
01155 {
01156         if(!fd) return 0;
01157 
01158 // Translate pure channel to a stream and a channel in the mpeg stream
01159         int stream, channel;
01160         to_streamchannel(file->current_channel, stream, channel);
01161         
01162         
01163 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
01164 
01165         mpeg3_set_sample(fd, 
01166                 file->current_sample,
01167                 stream);
01168         mpeg3_read_audio(fd, 
01169                 buffer,         /* Pointer to pre-allocated buffer of floats */
01170                 0,              /* Pointer to pre-allocated buffer of int16's */
01171                 channel,          /* Channel to decode */
01172                 len,         /* Number of samples to decode */
01173                 stream);          /* Stream containing the channel */
01174 
01175 
01176 //      last_sample = file->current_sample;
01177 
01178 //printf("FileMPEG::read_samples 100\n");
01179         return 0;
01180 }
01181 
01182 
01183 
01184 char* FileMPEG::strtocompression(char *string)
01185 {
01186         return "";
01187 }
01188 
01189 char* FileMPEG::compressiontostr(char *string)
01190 {
01191         return "";
01192 }
01193 
01194 
01195 
01196 
01197 
01198 
01199 
01200 FileMPEGVideo::FileMPEGVideo(FileMPEG *file)
01201  : Thread(1, 0, 0)
01202 {
01203         this->file = file;
01204         
01205         
01206         if(file->asset->vmpeg_cmodel == MPEG_YUV422)
01207         {
01208                 mpeg2enc_init_buffers();
01209                 mpeg2enc_set_w(file->asset->width);
01210                 mpeg2enc_set_h(file->asset->height);
01211                 mpeg2enc_set_rate(file->asset->frame_rate);
01212         }
01213 }
01214 
01215 FileMPEGVideo::~FileMPEGVideo()
01216 {
01217         Thread::join();
01218 }
01219 
01220 void FileMPEGVideo::run()
01221 {
01222         if(file->asset->vmpeg_cmodel == MPEG_YUV422)
01223         {
01224                 printf("FileMPEGVideo::run ");
01225                 for(int i = 0; i < file->vcommand_line.total; i++)
01226                 printf("%s ", file->vcommand_line.values[i]);
01227                 printf("\n");
01228                 mpeg2enc(file->vcommand_line.total, file->vcommand_line.values);
01229         }
01230         else
01231         {
01232                 while(1)
01233                 {
01234                         file->next_frame_lock->lock("FileMPEGVideo::run");
01235                         if(file->mjpeg_eof) 
01236                         {
01237                                 file->next_frame_done->unlock();
01238                                 break;
01239                         }
01240 
01241 
01242 
01243 // YUV4 sequence header
01244                         if(!file->wrote_header)
01245                         {
01246                                 file->wrote_header = 1;
01247 
01248                                 char string[BCTEXTLEN];
01249                                 char interlace_string[BCTEXTLEN];
01250                                 if(!file->asset->vmpeg_progressive)
01251                                 {
01252                                         sprintf(interlace_string, file->asset->vmpeg_field_order ? "b" : "t");
01253                                 }
01254                                 else
01255                                 {
01256                                         sprintf(interlace_string, "p");
01257                                 }
01258 
01259                                 fprintf(file->mjpeg_out, "YUV4MPEG2 W%d H%d F%d:%d I%s A%d:%d C%s\n",
01260                                         file->asset->width,
01261                                         file->asset->height,
01262                                         (int)(file->asset->frame_rate * 1001),
01263                                         1001,
01264                                         interlace_string,
01265                                         (int)(file->asset->aspect_ratio * 1000),
01266                                         1000,
01267                                         "420mpeg2");
01268                         }
01269 
01270 // YUV4 frame header
01271                         fprintf(file->mjpeg_out, "FRAME\n");
01272 
01273 // YUV data
01274                         if(!fwrite(file->mjpeg_y, file->asset->width * file->asset->height, 1, file->mjpeg_out))
01275                                 file->mjpeg_error = 1;
01276                         if(!fwrite(file->mjpeg_u, file->asset->width * file->asset->height / 4, 1, file->mjpeg_out))
01277                                 file->mjpeg_error = 1;
01278                         if(!fwrite(file->mjpeg_v, file->asset->width * file->asset->height / 4, 1, file->mjpeg_out))
01279                                 file->mjpeg_error = 1;
01280                         fflush(file->mjpeg_out);
01281 
01282                         file->next_frame_done->unlock();
01283                 }
01284                 pclose(file->mjpeg_out);
01285                 file->mjpeg_out = 0;
01286         }
01287 }
01288 
01289 
01290 
01291 
01292 
01293 
01294 
01295 
01296 
01297 
01298 
01299 
01300 
01301 
01302 
01303 
01304 
01305 
01306 
01307 
01308 FileMPEGAudio::FileMPEGAudio(FileMPEG *file)
01309  : Thread(1, 0, 0)
01310 {
01311         this->file = file;
01312         toolame_init_buffers();
01313 }
01314 
01315 FileMPEGAudio::~FileMPEGAudio()
01316 {
01317         Thread::join();
01318 }
01319 
01320 void FileMPEGAudio::run()
01321 {
01322         file->toolame_result = toolame(file->acommand_line.total, file->acommand_line.values);
01323 }
01324 
01325 
01326 
01327 
01328 
01329 
01330 
01331 
01332 MPEGConfigAudio::MPEGConfigAudio(BC_WindowBase *parent_window, Asset *asset)
01333  : BC_Window(PROGRAM_NAME ": Audio Compression",
01334         parent_window->get_abs_cursor_x(1),
01335         parent_window->get_abs_cursor_y(1),
01336         310,
01337         120,
01338         -1,
01339         -1,
01340         0,
01341         0,
01342         1)
01343 {
01344         this->parent_window = parent_window;
01345         this->asset = asset;
01346 }
01347 
01348 MPEGConfigAudio::~MPEGConfigAudio()
01349 {
01350 }
01351 
01352 int MPEGConfigAudio::create_objects()
01353 {
01354         int x = 10, y = 10;
01355         int x1 = 150;
01356         MPEGLayer *layer;
01357 
01358         add_tool(new BC_Title(x, y, _("Layer:")));
01359         add_tool(layer = new MPEGLayer(x1, y, this));
01360         layer->create_objects();
01361 
01362         y += 30;
01363         add_tool(new BC_Title(x, y, _("Kbits per second:")));
01364         add_tool(bitrate = new MPEGABitrate(x1, y, this));
01365         bitrate->create_objects();
01366         
01367         
01368         add_subwindow(new BC_OKButton(this));
01369         show_window();
01370         flush();
01371         return 0;
01372 }
01373 
01374 int MPEGConfigAudio::close_event()
01375 {
01376         set_done(0);
01377         return 1;
01378 }
01379 
01380 
01381 
01382 
01383 
01384 
01385 
01386 MPEGLayer::MPEGLayer(int x, int y, MPEGConfigAudio *gui)
01387  : BC_PopupMenu(x, y, 100, layer_to_string(gui->asset->ampeg_derivative))
01388 {
01389         this->gui = gui;
01390 }
01391 
01392 void MPEGLayer::create_objects()
01393 {
01394         add_item(new BC_MenuItem(layer_to_string(2)));
01395         add_item(new BC_MenuItem(layer_to_string(3)));
01396 }
01397 
01398 int MPEGLayer::handle_event()
01399 {
01400         gui->asset->ampeg_derivative = string_to_layer(get_text());
01401         gui->bitrate->set_layer(gui->asset->ampeg_derivative);
01402         return 1;
01403 };
01404 
01405 int MPEGLayer::string_to_layer(char *string)
01406 {
01407         if(!strcasecmp(layer_to_string(2), string))
01408                 return 2;
01409         if(!strcasecmp(layer_to_string(3), string))
01410                 return 3;
01411 
01412         return 2;
01413 }
01414 
01415 char* MPEGLayer::layer_to_string(int layer)
01416 {
01417         switch(layer)
01418         {
01419                 case 2:
01420                         return _("II");
01421                         break;
01422                 
01423                 case 3:
01424                         return _("III");
01425                         break;
01426                         
01427                 default:
01428                         return _("II");
01429                         break;
01430         }
01431 }
01432 
01433 
01434 
01435 
01436 
01437 
01438 
01439 MPEGABitrate::MPEGABitrate(int x, int y, MPEGConfigAudio *gui)
01440  : BC_PopupMenu(x, 
01441         y, 
01442         100, 
01443         bitrate_to_string(gui->string, gui->asset->ampeg_bitrate))
01444 {
01445         this->gui = gui;
01446 }
01447 
01448 void MPEGABitrate::create_objects()
01449 {
01450         set_layer(gui->asset->ampeg_derivative);
01451 }
01452 
01453 void MPEGABitrate::set_layer(int layer)
01454 {
01455         while(total_items())
01456         {
01457                 remove_item(0);
01458         }
01459 
01460         if(layer == 2)
01461         {
01462                 add_item(new BC_MenuItem("160"));
01463                 add_item(new BC_MenuItem("192"));
01464                 add_item(new BC_MenuItem("224"));
01465                 add_item(new BC_MenuItem("256"));
01466                 add_item(new BC_MenuItem("320"));
01467                 add_item(new BC_MenuItem("384"));
01468         }
01469         else
01470         {
01471                 add_item(new BC_MenuItem("8"));
01472                 add_item(new BC_MenuItem("16"));
01473                 add_item(new BC_MenuItem("24"));
01474                 add_item(new BC_MenuItem("32"));
01475                 add_item(new BC_MenuItem("40"));
01476                 add_item(new BC_MenuItem("48"));
01477                 add_item(new BC_MenuItem("56"));
01478                 add_item(new BC_MenuItem("64"));
01479                 add_item(new BC_MenuItem("80"));
01480                 add_item(new BC_MenuItem("96"));
01481                 add_item(new BC_MenuItem("112"));
01482                 add_item(new BC_MenuItem("128"));
01483                 add_item(new BC_MenuItem("144"));
01484                 add_item(new BC_MenuItem("160"));
01485                 add_item(new BC_MenuItem("192"));
01486                 add_item(new BC_MenuItem("224"));
01487                 add_item(new BC_MenuItem("256"));
01488                 add_item(new BC_MenuItem("320"));
01489         }
01490 }
01491 
01492 int MPEGABitrate::handle_event()
01493 {
01494         gui->asset->ampeg_bitrate = string_to_bitrate(get_text());
01495         return 1;
01496 };
01497 
01498 int MPEGABitrate::string_to_bitrate(char *string)
01499 {
01500         return atol(string);
01501 }
01502 
01503 
01504 char* MPEGABitrate::bitrate_to_string(char *string, int bitrate)
01505 {
01506         sprintf(string, "%d", bitrate);
01507         return string;
01508 }
01509 
01510 
01511 
01512 
01513 
01514 
01515 
01516 
01517 
01518 MPEGConfigVideo::MPEGConfigVideo(BC_WindowBase *parent_window, 
01519         Asset *asset)
01520  : BC_Window(PROGRAM_NAME ": Video Compression",
01521         parent_window->get_abs_cursor_x(1),
01522         parent_window->get_abs_cursor_y(1),
01523         500,
01524         400,
01525         -1,
01526         -1,
01527         0,
01528         0,
01529         1)
01530 {
01531         this->parent_window = parent_window;
01532         this->asset = asset;
01533         reset_cmodel();
01534 }
01535 
01536 MPEGConfigVideo::~MPEGConfigVideo()
01537 {
01538 }
01539 
01540 int MPEGConfigVideo::create_objects()
01541 {
01542         int x = 10, y = 10;
01543         int x1 = x + 150;
01544         int x2 = x + 300;
01545 
01546 
01547         add_subwindow(new BC_Title(x, y, _("Color model:")));
01548         add_subwindow(cmodel = new MPEGColorModel(x1, y, this));
01549         cmodel->create_objects();
01550         y += 30;
01551 
01552         update_cmodel_objs();
01553 
01554         add_subwindow(new BC_OKButton(this));
01555         show_window();
01556         flush();
01557         return 0;
01558 }
01559 
01560 int MPEGConfigVideo::close_event()
01561 {
01562         set_done(0);
01563         return 1;
01564 }
01565 
01566 
01567 void MPEGConfigVideo::delete_cmodel_objs()
01568 {
01569         delete preset;
01570         delete derivative;
01571         delete bitrate;
01572         delete fixed_bitrate;
01573         delete quant;
01574         delete fixed_quant;
01575         delete iframe_distance;
01576         delete pframe_distance;
01577         delete top_field_first;
01578         delete progressive;
01579         delete denoise;
01580         delete seq_codes;
01581         titles.remove_all_objects();
01582         reset_cmodel();
01583 }
01584 
01585 void MPEGConfigVideo::reset_cmodel()
01586 {
01587         preset = 0;
01588         derivative = 0;
01589         bitrate = 0;
01590         fixed_bitrate = 0;
01591         quant = 0;
01592         fixed_quant = 0;
01593         iframe_distance = 0;
01594         pframe_distance = 0;
01595         top_field_first = 0;
01596         progressive = 0;
01597         denoise = 0;
01598         seq_codes = 0;
01599 }
01600 
01601 void MPEGConfigVideo::update_cmodel_objs()
01602 {
01603         BC_Title *title;
01604         int x = 10;
01605         int y = 40;
01606         int x1 = x + 150;
01607         int x2 = x + 280;
01608 
01609         delete_cmodel_objs();
01610 
01611         if(asset->vmpeg_cmodel == MPEG_YUV420)
01612         {
01613                 add_subwindow(title = new BC_Title(x, y + 5, _("Format Preset:")));
01614                 titles.append(title);
01615                 add_subwindow(preset = new MPEGPreset(x1, y, this));
01616                 preset->create_objects();
01617                 y += 30;
01618         }
01619 
01620         add_subwindow(title = new BC_Title(x, y + 5, _("Derivative:")));
01621         titles.append(title);
01622         add_subwindow(derivative = new MPEGDerivative(x1, y, this));
01623         derivative->create_objects();
01624         y += 30;
01625 
01626         add_subwindow(title = new BC_Title(x, y + 5, _("Bitrate:")));
01627         titles.append(title);
01628         add_subwindow(bitrate = new MPEGBitrate(x1, y, this));
01629         add_subwindow(fixed_bitrate = new MPEGFixedBitrate(x2, y, this));
01630         y += 30;
01631 
01632         add_subwindow(title = new BC_Title(x, y, _("Quantization:")));
01633         titles.append(title);
01634         quant = new MPEGQuant(x1, y, this);
01635         quant->create_objects();
01636         add_subwindow(fixed_quant = new MPEGFixedQuant(x2, y, this));
01637         y += 30;
01638 
01639         add_subwindow(title = new BC_Title(x, y, _("I frame distance:")));
01640         titles.append(title);
01641         iframe_distance = new MPEGIFrameDistance(x1, y, this);
01642         iframe_distance->create_objects();
01643         y += 30;
01644 
01645         if(asset->vmpeg_cmodel == MPEG_YUV420)
01646         {
01647                 add_subwindow(title = new BC_Title(x, y, _("P frame distance:")));
01648                 titles.append(title);
01649                 pframe_distance = new MPEGPFrameDistance(x1, y, this);
01650                 pframe_distance->create_objects();
01651                 y += 30;
01652 
01653                 add_subwindow(top_field_first = new BC_CheckBox(x, y, &asset->vmpeg_field_order, _("Bottom field first")));
01654                 y += 30;
01655         }
01656 
01657         add_subwindow(progressive = new BC_CheckBox(x, y, &asset->vmpeg_progressive, _("Progressive frames")));
01658         y += 30;
01659         add_subwindow(denoise = new BC_CheckBox(x, y, &asset->vmpeg_denoise, _("Denoise")));
01660         y += 30;
01661         add_subwindow(seq_codes = new BC_CheckBox(x, y, &asset->vmpeg_seq_codes, _("Sequence start codes in every GOP")));
01662 
01663 }
01664 
01665 
01666 
01667 
01668 
01669 
01670 
01671 
01672 
01673 
01674 
01675 
01676 
01677 MPEGDerivative::MPEGDerivative(int x, int y, MPEGConfigVideo *gui)
01678  : BC_PopupMenu(x, y, 150, derivative_to_string(gui->asset->vmpeg_derivative))
01679 {
01680         this->gui = gui;
01681 }
01682 
01683 void MPEGDerivative::create_objects()
01684 {
01685         add_item(new BC_MenuItem(derivative_to_string(1)));
01686         add_item(new BC_MenuItem(derivative_to_string(2)));
01687 }
01688 
01689 int MPEGDerivative::handle_event()
01690 {
01691         gui->asset->vmpeg_derivative = string_to_derivative(get_text());
01692         return 1;
01693 };
01694 
01695 int MPEGDerivative::string_to_derivative(char *string)
01696 {
01697         if(!strcasecmp(derivative_to_string(1), string))
01698                 return 1;
01699         if(!strcasecmp(derivative_to_string(2), string))
01700                 return 2;
01701 
01702         return 1;
01703 }
01704 
01705 char* MPEGDerivative::derivative_to_string(int derivative)
01706 {
01707         switch(derivative)
01708         {
01709                 case 1:
01710                         return _("MPEG-1");
01711                         break;
01712                 
01713                 case 2:
01714                         return _("MPEG-2");
01715                         break;
01716                         
01717                 default:
01718                         return _("MPEG-1");
01719                         break;
01720         }
01721 }
01722 
01723 
01724 
01725 
01726 
01727 
01728 
01729 
01730 
01731 
01732 
01733 MPEGPreset::MPEGPreset(int x, int y, MPEGConfigVideo *gui)
01734  : BC_PopupMenu(x, y, 200, value_to_string(gui->asset->vmpeg_preset))
01735 {
01736         this->gui = gui;
01737 }
01738 
01739 void MPEGPreset::create_objects()
01740 {
01741         for(int i = 0; i < 10; i++)
01742         {
01743                 add_item(new BC_MenuItem(value_to_string(i)));
01744         }
01745 }
01746 
01747 int MPEGPreset::handle_event()
01748 {
01749         gui->asset->vmpeg_preset = string_to_value(get_text());
01750         return 1;
01751 }
01752 
01753 int MPEGPreset::string_to_value(char *string)
01754 {
01755         for(int i = 0; i < 10; i++)
01756         {
01757                 if(!strcasecmp(value_to_string(i), string))
01758                         return i;
01759         }
01760         return 0;
01761 }
01762 
01763 char* MPEGPreset::value_to_string(int derivative)
01764 {
01765         switch(derivative)
01766         {
01767                 case 0: return _("Generic MPEG-1"); break;
01768                 case 1: return _("standard VCD"); break;
01769                 case 2: return _("user VCD"); break;
01770                 case 3: return _("Generic MPEG-2"); break;
01771                 case 4: return _("standard SVCD"); break;
01772                 case 5: return _("user SVCD"); break;
01773                 case 6: return _("VCD Still sequence"); break;
01774                 case 7: return _("SVCD Still sequence"); break;
01775                 case 8: return _("DVD NAV"); break;
01776                 case 9: return _("DVD"); break;
01777                 default: return _("Generic MPEG-1"); break;
01778         }
01779 }
01780 
01781 
01782 
01783 
01784 
01785 
01786 
01787 
01788 
01789 
01790 
01791 MPEGBitrate::MPEGBitrate(int x, int y, MPEGConfigVideo *gui)
01792  : BC_TextBox(x, y, 100, 1, gui->asset->vmpeg_bitrate)
01793 {
01794         this->gui = gui;
01795 }
01796 
01797 
01798 int MPEGBitrate::handle_event()
01799 {
01800         gui->asset->vmpeg_bitrate = atol(get_text());
01801         return 1;
01802 };
01803 
01804 
01805 
01806 
01807 
01808 MPEGQuant::MPEGQuant(int x, int y, MPEGConfigVideo *gui)
01809  : BC_TumbleTextBox(gui, 
01810         (int64_t)gui->asset->vmpeg_quantization, 
01811         (int64_t)1,
01812         (int64_t)100,
01813         x, 
01814         y,
01815         100)
01816 {
01817         this->gui = gui;
01818 }
01819 
01820 int MPEGQuant::handle_event()
01821 {
01822         gui->asset->vmpeg_quantization = atol(get_text());
01823         return 1;
01824 };
01825 
01826 MPEGFixedBitrate::MPEGFixedBitrate(int x, int y, MPEGConfigVideo *gui)
01827  : BC_Radial(x, y, gui->asset->vmpeg_fix_bitrate, _("Fixed bitrate"))
01828 {
01829         this->gui = gui;
01830 }
01831 
01832 int MPEGFixedBitrate::handle_event()
01833 {
01834         update(1);
01835         gui->asset->vmpeg_fix_bitrate = 1;
01836         gui->fixed_quant->update(0);
01837         return 1;
01838 };
01839 
01840 MPEGFixedQuant::MPEGFixedQuant(int x, int y, MPEGConfigVideo *gui)
01841  : BC_Radial(x, y, !gui->asset->vmpeg_fix_bitrate, _("Fixed quantization"))
01842 {
01843         this->gui = gui;
01844 }
01845 
01846 int MPEGFixedQuant::handle_event()
01847 {
01848         update(1);
01849         gui->asset->vmpeg_fix_bitrate = 0;
01850         gui->fixed_bitrate->update(0);
01851         return 1;
01852 };
01853 
01854 
01855 
01856 
01857 
01858 
01859 
01860 
01861 
01862 MPEGIFrameDistance::MPEGIFrameDistance(int x, int y, MPEGConfigVideo *gui)
01863  : BC_TumbleTextBox(gui, 
01864         (int64_t)gui->asset->vmpeg_iframe_distance, 
01865         (int64_t)1,
01866         (int64_t)100,
01867         x, 
01868         y,
01869         50)
01870 {
01871         this->gui = gui;
01872 }
01873 
01874 int MPEGIFrameDistance::handle_event()
01875 {
01876         gui->asset->vmpeg_iframe_distance = atoi(get_text());
01877         return 1;
01878 }
01879 
01880 
01881 
01882 
01883 
01884 
01885 
01886 MPEGPFrameDistance::MPEGPFrameDistance(int x, int y, MPEGConfigVideo *gui)
01887  : BC_TumbleTextBox(gui, 
01888         (int64_t)gui->asset->vmpeg_pframe_distance, 
01889         (int64_t)0,
01890         (int64_t)2,
01891         x, 
01892         y,
01893         50)
01894 {
01895         this->gui = gui;
01896 }
01897 
01898 int MPEGPFrameDistance::handle_event()
01899 {
01900         gui->asset->vmpeg_pframe_distance = atoi(get_text());
01901         return 1;
01902 }
01903 
01904 
01905 
01906 
01907 
01908 
01909 
01910 
01911 MPEGColorModel::MPEGColorModel(int x, int y, MPEGConfigVideo *gui)
01912  : BC_PopupMenu(x, y, 150, cmodel_to_string(gui->asset->vmpeg_cmodel))
01913 {
01914         this->gui = gui;
01915 }
01916 
01917 void MPEGColorModel::create_objects()
01918 {
01919         add_item(new BC_MenuItem(cmodel_to_string(0)));
01920         add_item(new BC_MenuItem(cmodel_to_string(1)));
01921 }
01922 
01923 int MPEGColorModel::handle_event()
01924 {
01925         gui->asset->vmpeg_cmodel = string_to_cmodel(get_text());
01926         gui->update_cmodel_objs();
01927         return 1;
01928 };
01929 
01930 int MPEGColorModel::string_to_cmodel(char *string)
01931 {
01932         if(!strcasecmp(cmodel_to_string(0), string))
01933                 return 0;
01934         if(!strcasecmp(cmodel_to_string(1), string))
01935                 return 1;
01936         return 1;
01937 }
01938 
01939 char* MPEGColorModel::cmodel_to_string(int cmodel)
01940 {
01941         switch(cmodel)
01942         {
01943                 case MPEG_YUV420:
01944                         return _("YUV 4:2:0");
01945                         break;
01946                 
01947                 case MPEG_YUV422:
01948                         return _("YUV 4:2:2");
01949                         break;
01950                         
01951                 default:
01952                         return _("YUV 4:2:0");
01953                         break;
01954         }
01955 }
01956 
01957 
01958 
01959 
01960 
01961 

Generated on Sun Jan 8 13:38:54 2006 for Cinelerra-svn by  doxygen 1.4.4