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