2 #include "bcprogressbox.h"
11 #include "filesystem.h"
13 #include "indexfile.h"
14 #include "interlacemodes.h"
16 #include "mwindow.inc"
17 #include "preferences.h"
19 #include "videodevice.inc"
29 #define MJPEG_EXE PLUGIN_DIR "/mpeg2enc.plugin"
37 // M JPEG dependancies
38 static double frame_rate_codes[] =
51 static double aspect_ratio_codes[] =
67 FileMPEG::FileMPEG(Asset *asset, File *file)
68 : FileBase(asset, file)
71 // May also be VMPEG or AMPEG if write status.
72 if(asset->format == FILE_UNKNOWN) asset->format = FILE_MPEG;
73 asset->byte_order = 0;
74 next_frame_lock = new Condition(0, "FileMPEG::next_frame_lock");
75 next_frame_done = new Condition(0, "FileMPEG::next_frame_done");
81 delete next_frame_lock;
82 delete next_frame_done;
85 void FileMPEG::get_parameters(BC_WindowBase *parent_window,
87 BC_WindowBase* &format_window,
91 if(audio_options && asset->format == FILE_AMPEG)
93 MPEGConfigAudio *window = new MPEGConfigAudio(parent_window, asset);
94 format_window = window;
95 window->create_objects();
100 if(video_options && asset->format == FILE_VMPEG)
102 MPEGConfigVideo *window = new MPEGConfigVideo(parent_window, asset);
103 format_window = window;
104 window->create_objects();
105 window->run_window();
110 int FileMPEG::check_sig(Asset *asset)
112 return mpeg3_check_sig(asset->path);
115 int FileMPEG::reset_parameters_derived()
130 toolame_allocation = 0;
137 lame_output_allocation = 0;
143 // Just create the Quicktime objects since this routine is also called
145 int FileMPEG::open_file(int rd, int wr)
153 if(!(fd = mpeg3_open(asset->path)))
155 printf("FileMPEG::open_file %s\n", asset->path);
160 // Determine if the file needs a table of contents and create one if needed.
161 if(!mpeg3_has_toc(fd))
163 // If it has video it must be scanned since video has keyframes.
164 if(mpeg3_total_vstreams(fd))
166 if(create_index()) return 1;
170 mpeg3_set_cpus(fd, file->cpus);
172 asset->audio_data = mpeg3_has_audio(fd);
173 if(asset->audio_data)
176 for(int i = 0; i < mpeg3_total_astreams(fd); i++)
178 asset->channels += mpeg3_audio_channels(fd, i);
180 if(!asset->sample_rate)
181 asset->sample_rate = mpeg3_sample_rate(fd, 0);
182 asset->audio_length = mpeg3_audio_samples(fd, 0);
185 asset->video_data = mpeg3_has_video(fd);
186 if(asset->video_data)
188 asset->layers = mpeg3_total_vstreams(fd);
189 asset->width = mpeg3_video_width(fd, 0);
190 asset->height = mpeg3_video_height(fd, 0);
191 asset->interlace_mode = BC_ILACE_MODE_UNDETECTED; // TODO: (to do this, start at hvirtualcvs/libmpeg3/headers.c
192 // and find out how to decode info from the header)
193 asset->video_length = mpeg3_video_frames(fd, 0);
194 asset->vmpeg_cmodel =
195 (mpeg3_colormodel(fd, 0) == MPEG3_YUV422P) ? MPEG_YUV422 : MPEG_YUV420;
196 if(!asset->frame_rate)
197 asset->frame_rate = mpeg3_frame_rate(fd, 0);
204 if(wr && asset->format == FILE_VMPEG)
206 // Heroine Virtual encoder
207 if(asset->vmpeg_cmodel == MPEG_YUV422)
209 char bitrate_string[BCTEXTLEN];
210 char quant_string[BCTEXTLEN];
211 char iframe_string[BCTEXTLEN];
213 sprintf(bitrate_string, "%d", asset->vmpeg_bitrate);
214 sprintf(quant_string, "%d", asset->vmpeg_quantization);
215 sprintf(iframe_string, "%d", asset->vmpeg_iframe_distance);
217 // Construct command line
220 append_vcommand_line("mpeg2enc");
223 if(asset->aspect_ratio > 0)
225 append_vcommand_line("-a");
226 if(EQUIV(asset->aspect_ratio, 1))
227 append_vcommand_line("1");
229 if(EQUIV(asset->aspect_ratio, 1.333))
230 append_vcommand_line("2");
232 if(EQUIV(asset->aspect_ratio, 1.777))
233 append_vcommand_line("3");
235 if(EQUIV(asset->aspect_ratio, 2.11))
236 append_vcommand_line("4");
239 append_vcommand_line(asset->vmpeg_derivative == 1 ? "-1" : "");
240 append_vcommand_line(asset->vmpeg_cmodel == MPEG_YUV422 ? "-422" : "");
241 if(asset->vmpeg_fix_bitrate)
243 append_vcommand_line("-b");
244 append_vcommand_line(bitrate_string);
248 append_vcommand_line("-q");
249 append_vcommand_line(quant_string);
251 append_vcommand_line(!asset->vmpeg_fix_bitrate ? quant_string : "");
252 append_vcommand_line("-n");
253 append_vcommand_line(iframe_string);
254 append_vcommand_line(asset->vmpeg_progressive ? "-p" : "");
255 append_vcommand_line(asset->vmpeg_denoise ? "-d" : "");
256 append_vcommand_line(file->cpus <= 1 ? "-u" : "");
257 append_vcommand_line(asset->vmpeg_seq_codes ? "-g" : "");
258 append_vcommand_line(asset->path);
260 video_out = new FileMPEGVideo(this);
265 // mjpegtools encoder
267 char string[BCTEXTLEN];
268 sprintf(mjpeg_command, MJPEG_EXE);
270 if(asset->vmpeg_fix_bitrate)
272 sprintf(string, " -b %d -q %d", asset->vmpeg_bitrate, 0);
276 sprintf(string, " -b %d -q %d", asset->vmpeg_bitrate, asset->vmpeg_quantization);
278 strcat(mjpeg_command, string);
286 int aspect_ratio_code = -1;
287 if(asset->aspect_ratio > 0)
289 for(int i = 0; i < sizeof(aspect_ratio_codes) / sizeof(double); i++)
291 if(EQUIV(aspect_ratio_codes[i], asset->aspect_ratio))
293 aspect_ratio_code = i;
298 if(aspect_ratio_code < 0)
300 printf("FileMPEG::open_file: Unsupported aspect ratio %f\n", asset->aspect_ratio);
301 aspect_ratio_code = 2;
303 sprintf(string, " -a %d", aspect_ratio_code);
304 strcat(mjpeg_command, string);
312 int frame_rate_code = -1;
313 for(int i = 1; sizeof(frame_rate_codes) / sizeof(double); ++i)
315 if(EQUIV(asset->frame_rate, frame_rate_codes[i]))
321 if(frame_rate_code < 0)
324 printf("FileMPEG::open_file: Unsupported frame rate %f\n", asset->frame_rate);
326 sprintf(string, " -F %d", frame_rate_code);
327 strcat(mjpeg_command, string);
333 strcat(mjpeg_command, asset->vmpeg_progressive ? " -I 0" : " -I 1");
337 sprintf(string, " -M %d", file->cpus);
338 strcat(mjpeg_command, string);
341 if(!asset->vmpeg_progressive)
343 strcat(mjpeg_command, asset->vmpeg_field_order ? " -z b" : " -z t");
347 sprintf(string, " -f %d", asset->vmpeg_preset);
348 strcat(mjpeg_command, string);
351 sprintf(string, " -g %d -G %d", asset->vmpeg_iframe_distance, asset->vmpeg_iframe_distance);
352 strcat(mjpeg_command, string);
355 if(asset->vmpeg_seq_codes) strcat(mjpeg_command, " -s");
358 sprintf(string, " -R %d", CLAMP(asset->vmpeg_pframe_distance, 0, 2));
359 strcat(mjpeg_command, string);
361 sprintf(string, " -o %s", asset->path);
362 strcat(mjpeg_command, string);
366 printf("FileMPEG::open_file: Running %s\n", mjpeg_command);
367 if(!(mjpeg_out = popen(mjpeg_command, "w")))
369 perror("FileMPEG::open_file");
372 video_out = new FileMPEGVideo(this);
377 if(wr && asset->format == FILE_AMPEG)
379 char command_line[BCTEXTLEN];
380 char encoder_string[BCTEXTLEN];
381 char argument_string[BCTEXTLEN];
383 //printf("FileMPEG::open_file 1 %d\n", asset->ampeg_derivative);
384 encoder_string[0] = 0;
386 if(asset->ampeg_derivative == 2)
388 char string[BCTEXTLEN];
389 append_acommand_line("toolame");
390 append_acommand_line("-m");
391 append_acommand_line((asset->channels >= 2) ? "j" : "m");
392 sprintf(string, "%f", (float)asset->sample_rate / 1000);
393 append_acommand_line("-s");
394 append_acommand_line(string);
395 sprintf(string, "%d", asset->ampeg_bitrate);
396 append_acommand_line("-b");
397 append_acommand_line(string);
398 append_acommand_line("-");
399 append_acommand_line(asset->path);
401 audio_out = new FileMPEGAudio(this);
405 if(asset->ampeg_derivative == 3)
407 lame_global = lame_init();
408 lame_set_brate(lame_global, asset->ampeg_bitrate / 1000);
409 lame_set_quality(lame_global, 0);
410 lame_set_in_samplerate(lame_global,
412 if((result = lame_init_params(lame_global)) < 0)
414 printf(_("encode: lame_init_params returned %d\n"), result);
415 lame_close(lame_global);
419 if(!(lame_fd = fopen(asset->path, "w")))
421 perror("FileMPEG::open_file");
422 lame_close(lame_global);
428 printf("FileMPEG::open_file: ampeg_derivative=%d\n", asset->ampeg_derivative);
434 //printf("FileMPEG::open_file 100\n");
445 int FileMPEG::create_index()
447 // Calculate TOC path
448 char index_filename[BCTEXTLEN];
449 char source_filename[BCTEXTLEN];
450 IndexFile::get_index_filename(source_filename,
451 file->preferences->index_directory,
454 char *ptr = strrchr(index_filename, '.');
457 sprintf(ptr, ".toc");
459 // Test existence of TOC
460 FILE *test = fopen(index_filename, "r");
463 // Reopen with table of contents
468 // Create progress window.
469 // This gets around the fact that MWindowGUI is locked.
470 char progress_title[BCTEXTLEN];
471 char string[BCTEXTLEN];
472 sprintf(progress_title, "Creating %s\n", index_filename);
474 mpeg3_t *index_file = mpeg3_start_toc(asset->path, index_filename, &total_bytes);
475 struct timeval new_time;
476 struct timeval prev_time;
477 struct timeval start_time;
478 struct timeval current_time;
479 gettimeofday(&prev_time, 0);
480 gettimeofday(&start_time, 0);
482 BC_ProgressBox *progress = new BC_ProgressBox(-1,
490 int64_t bytes_processed;
491 mpeg3_do_toc(index_file, &bytes_processed);
492 gettimeofday(&new_time, 0);
494 if(new_time.tv_sec - prev_time.tv_sec >= 1)
496 gettimeofday(¤t_time, 0);
497 int64_t elapsed_seconds = current_time.tv_sec - start_time.tv_sec;
498 int64_t total_seconds = elapsed_seconds * total_bytes / bytes_processed;
499 int64_t eta = total_seconds - elapsed_seconds;
500 progress->update(bytes_processed, 1);
506 progress->update_title(string, 1);
507 // fprintf(stderr, "ETA: %dm%ds \r",
508 // bytes_processed * 100 / total_bytes,
512 prev_time = new_time;
514 if(bytes_processed >= total_bytes) break;
515 if(progress->is_cancelled())
522 mpeg3_stop_toc(index_file);
524 progress->stop_progress();
528 remove(index_filename);
536 // Reopen file from index path instead of asset path.
537 if(fd) mpeg3_close(fd);
538 if(!(fd = mpeg3_open(index_filename)))
551 void FileMPEG::append_vcommand_line(const char *string)
555 char *argv = strdup(string);
556 vcommand_line.append(argv);
560 void FileMPEG::append_acommand_line(const char *string)
564 char *argv = strdup(string);
565 acommand_line.append(argv);
570 int FileMPEG::close_file()
573 next_frame_lock->unlock();
582 // End of sequence signal
583 if(file->asset->vmpeg_cmodel == MPEG_YUV422)
585 mpeg2enc_set_input_buffers(1, 0, 0, 0);
591 vcommand_line.remove_all_objects();
592 acommand_line.remove_all_objects();
596 toolame_send_buffer(0, 0);
602 lame_close(lame_global);
604 if(temp_frame) delete temp_frame;
605 if(toolame_temp) delete [] toolame_temp;
607 if(lame_temp[0]) delete [] lame_temp[0];
608 if(lame_temp[1]) delete [] lame_temp[1];
609 if(lame_output) delete [] lame_output;
610 if(lame_fd) fclose(lame_fd);
612 if(mjpeg_out) fclose(mjpeg_out);
615 FileBase::close_file();
619 int FileMPEG::get_best_colormodel(Asset *asset, int driver)
621 //printf("FileMPEG::get_best_colormodel 1\n");
626 if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
627 if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
629 case PLAYBACK_X11_XV:
630 if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
631 if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
637 case PLAYBACK_DV1394:
638 case PLAYBACK_FIREWIRE:
643 if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
644 if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
650 case CAPTURE_FIREWIRE:
651 case CAPTURE_IEC61883:
655 //printf("FileMPEG::get_best_colormodel 100\n");
658 int FileMPEG::colormodel_supported(int colormodel)
663 int FileMPEG::get_index(char *index_path)
668 // Convert the index tables from tracks to channels.
669 if(mpeg3_index_tracks(fd))
671 // Calculate size of buffer needed for all channels
673 for(int i = 0; i < mpeg3_index_tracks(fd); i++)
675 buffer_size += mpeg3_index_size(fd, i) *
676 mpeg3_index_channels(fd, i) *
680 asset->index_buffer = new float[buffer_size];
682 // Size of index buffer in floats
683 int current_offset = 0;
684 // Current asset channel
685 int current_channel = 0;
686 asset->index_zoom = mpeg3_index_zoom(fd);
687 asset->index_offsets = new int64_t[asset->channels];
688 asset->index_sizes = new int64_t[asset->channels];
689 for(int i = 0; i < mpeg3_index_tracks(fd); i++)
691 for(int j = 0; j < mpeg3_index_channels(fd, i); j++)
693 asset->index_offsets[current_channel] = current_offset;
694 asset->index_sizes[current_channel] = mpeg3_index_size(fd, i) * 2;
695 memcpy(asset->index_buffer + current_offset,
696 mpeg3_index_data(fd, i, j),
697 mpeg3_index_size(fd, i) * sizeof(float) * 2);
699 current_offset += mpeg3_index_size(fd, i) * 2;
705 asset->index_bytes = fs.get_size(asset->path);
707 asset->write_index(index_path, buffer_size * sizeof(float));
708 delete [] asset->index_buffer;
717 int FileMPEG::can_copy_from(Edit *edit, int64_t position)
723 int FileMPEG::set_audio_position(int64_t sample)
729 to_streamchannel(file->current_channel, stream, channel);
731 //printf("FileMPEG::set_audio_position %d %d %d\n", sample, mpeg3_get_sample(fd, stream), last_sample);
732 if(sample != mpeg3_get_sample(fd, stream) &&
733 sample != last_sample)
735 if(sample >= 0 && sample < asset->audio_length)
737 //printf("FileMPEG::set_audio_position seeking stream %d\n", sample);
738 return mpeg3_set_sample(fd, sample, stream);
747 int FileMPEG::set_video_position(int64_t x)
750 if(x >= 0 && x < asset->video_length)
752 mpeg3_set_frame(fd, x, file->current_layer);
759 int FileMPEG::write_samples(double **buffer, int64_t len)
763 //printf("FileMPEG::write_samples 1\n");
764 if(asset->ampeg_derivative == 2)
767 int channels = MIN(asset->channels, 2);
768 int64_t audio_size = len * channels * 2;
769 if(toolame_allocation < audio_size)
771 if(toolame_temp) delete [] toolame_temp;
772 toolame_temp = new unsigned char[audio_size];
773 toolame_allocation = audio_size;
776 for(int i = 0; i < channels; i++)
778 int16_t *output = ((int16_t*)toolame_temp) + i;
779 double *input = buffer[i];
780 for(int j = 0; j < len; j++)
782 int sample = (int)(*input * 0x7fff);
783 *output = (int16_t)(CLIP(sample, -0x8000, 0x7fff));
788 result = toolame_send_buffer((char*)toolame_temp, audio_size);
791 if(asset->ampeg_derivative == 3)
793 int channels = MIN(asset->channels, 2);
794 int64_t audio_size = len * channels;
795 if(!lame_global) return 1;
796 if(!lame_fd) return 1;
797 if(lame_allocation < audio_size)
799 if(lame_temp[0]) delete [] lame_temp[0];
800 if(lame_temp[1]) delete [] lame_temp[1];
801 lame_temp[0] = new float[audio_size];
802 lame_temp[1] = new float[audio_size];
803 lame_allocation = audio_size;
806 if(lame_output_allocation < audio_size * 4)
808 if(lame_output) delete [] lame_output;
809 lame_output_allocation = audio_size * 4;
810 lame_output = new char[lame_output_allocation];
813 for(int i = 0; i < channels; i++)
815 float *output = lame_temp[i];
816 double *input = buffer[i];
817 for(int j = 0; j < len; j++)
819 *output++ = *input++ * (float)32768;
823 result = lame_encode_buffer_float(lame_global,
825 (channels > 1) ? lame_temp[1] : lame_temp[0],
827 (unsigned char*)lame_output,
828 lame_output_allocation);
831 char *real_output = lame_output;
835 for(int i = 0; i < bytes; i++)
838 real_output = &lame_output[i];
844 if(bytes > 0 && lame_started)
846 result = !fwrite(real_output, 1, bytes, lame_fd);
848 perror("FileMPEG::write_samples");
860 int FileMPEG::write_frames(VFrame ***frames, int len)
866 int temp_w = (int)((asset->width + 15) / 16) * 16;
871 (asset->vmpeg_cmodel == MPEG_YUV420) ? BC_YUV420P : BC_YUV422P;
874 // Height depends on progressiveness
875 if(asset->vmpeg_progressive || asset->vmpeg_derivative == 1)
876 temp_h = (int)((asset->height + 15) / 16) * 16;
878 temp_h = (int)((asset->height + 31) / 32) * 32;
880 //printf("FileMPEG::write_frames 1\n");
882 // Only 1 layer is supported in MPEG output
883 for(int i = 0; i < 1; i++)
885 for(int j = 0; j < len && !result; j++)
887 VFrame *frame = frames[i][j];
891 if(asset->vmpeg_cmodel == MPEG_YUV422)
893 if(frame->get_w() == temp_w &&
894 frame->get_h() == temp_h &&
895 frame->get_color_model() == output_cmodel)
897 mpeg2enc_set_input_buffers(0,
898 (char*)frame->get_y(),
899 (char*)frame->get_u(),
900 (char*)frame->get_v());
905 (temp_frame->get_w() != temp_w ||
906 temp_frame->get_h() != temp_h ||
907 temp_frame->get_color_model() || output_cmodel))
916 temp_frame = new VFrame(0,
922 cmodel_transfer(temp_frame->get_rows(),
938 frame->get_color_model(),
939 temp_frame->get_color_model(),
944 mpeg2enc_set_input_buffers(0,
945 (char*)temp_frame->get_y(),
946 (char*)temp_frame->get_u(),
947 (char*)temp_frame->get_v());
952 // MJPEG uses the same dimensions as the input
953 if(frame->get_color_model() == output_cmodel)
955 mjpeg_y = frame->get_y();
956 mjpeg_u = frame->get_u();
957 mjpeg_v = frame->get_v();
963 temp_frame = new VFrame(0,
969 cmodel_transfer(temp_frame->get_rows(),
985 frame->get_color_model(),
986 temp_frame->get_color_model(),
991 mjpeg_y = temp_frame->get_y();
992 mjpeg_u = temp_frame->get_u();
993 mjpeg_v = temp_frame->get_v();
999 next_frame_lock->unlock();
1000 next_frame_done->lock("FileMPEG::write_frames");
1001 if(mjpeg_error) result = 1;
1017 int FileMPEG::read_frame(VFrame *frame)
1024 if(mpeg3_colormodel(fd, 0) == MPEG3_YUV420P)
1025 src_cmodel = BC_YUV420P;
1027 if(mpeg3_colormodel(fd, 0) == MPEG3_YUV422P)
1028 src_cmodel = BC_YUV422P;
1031 switch(frame->get_color_model())
1035 case MPEG3_BGRA8888:
1037 case MPEG3_RGBA8888:
1038 case MPEG3_RGBA16161616:
1039 mpeg3_read_frame(fd,
1040 frame->get_rows(), /* Array of pointers to the start of each output row */
1041 0, /* Location in input frame to take picture */
1045 asset->width, /* Dimensions of output_rows */
1047 frame->get_color_model(), /* One of the color model #defines */
1048 file->current_layer);
1053 // Read these directly
1054 if(frame->get_color_model() == src_cmodel)
1056 mpeg3_read_yuvframe(fd,
1057 (char*)frame->get_y(),
1058 (char*)frame->get_u(),
1059 (char*)frame->get_v(),
1064 file->current_layer);
1068 // Process through temp frame
1071 mpeg3_read_yuvframe_ptr(fd,
1075 file->current_layer);
1078 cmodel_transfer(frame->get_rows(),
1095 frame->get_color_model(),
1108 void FileMPEG::to_streamchannel(int channel, int &stream_out, int &channel_out)
1110 for(stream_out = 0, channel_out = file->current_channel;
1111 stream_out < mpeg3_total_astreams(fd) &&
1112 channel_out >= mpeg3_audio_channels(fd, stream_out);
1113 channel_out -= mpeg3_audio_channels(fd, stream_out), stream_out++)
1117 int FileMPEG::read_samples(double *buffer, int64_t len)
1121 // This is directed to a FileMPEGBuffer
1122 float *temp_float = new float[len];
1123 // Translate pure channel to a stream and a channel in the mpeg stream
1124 int stream, channel;
1125 to_streamchannel(file->current_channel, stream, channel);
1129 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
1131 mpeg3_set_sample(fd,
1132 file->current_sample,
1134 mpeg3_read_audio(fd,
1135 temp_float, /* Pointer to pre-allocated buffer of floats */
1136 0, /* Pointer to pre-allocated buffer of int16's */
1137 channel, /* Channel to decode */
1138 len, /* Number of samples to decode */
1139 stream); /* Stream containing the channel */
1142 // last_sample = file->current_sample;
1143 for(int i = 0; i < len; i++) buffer[i] = temp_float[i];
1145 delete [] temp_float;
1149 int FileMPEG::prefer_samples_float()
1154 int FileMPEG::read_samples_float(float *buffer, int64_t len)
1158 // Translate pure channel to a stream and a channel in the mpeg stream
1159 int stream, channel;
1160 to_streamchannel(file->current_channel, stream, channel);
1163 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
1165 mpeg3_set_sample(fd,
1166 file->current_sample,
1168 mpeg3_read_audio(fd,
1169 buffer, /* Pointer to pre-allocated buffer of floats */
1170 0, /* Pointer to pre-allocated buffer of int16's */
1171 channel, /* Channel to decode */
1172 len, /* Number of samples to decode */
1173 stream); /* Stream containing the channel */
1176 // last_sample = file->current_sample;
1178 //printf("FileMPEG::read_samples 100\n");
1184 char* FileMPEG::strtocompression(char *string)
1189 char* FileMPEG::compressiontostr(char *string)
1200 FileMPEGVideo::FileMPEGVideo(FileMPEG *file)
1206 if(file->asset->vmpeg_cmodel == MPEG_YUV422)
1208 mpeg2enc_init_buffers();
1209 mpeg2enc_set_w(file->asset->width);
1210 mpeg2enc_set_h(file->asset->height);
1211 mpeg2enc_set_rate(file->asset->frame_rate);
1215 FileMPEGVideo::~FileMPEGVideo()
1220 void FileMPEGVideo::run()
1222 if(file->asset->vmpeg_cmodel == MPEG_YUV422)
1224 printf("FileMPEGVideo::run ");
1225 for(int i = 0; i < file->vcommand_line.total; i++)
1226 printf("%s ", file->vcommand_line.values[i]);
1228 mpeg2enc(file->vcommand_line.total, file->vcommand_line.values);
1234 file->next_frame_lock->lock("FileMPEGVideo::run");
1237 file->next_frame_done->unlock();
1243 // YUV4 sequence header
1244 if(!file->wrote_header)
1246 file->wrote_header = 1;
1248 char string[BCTEXTLEN];
1249 char interlace_string[BCTEXTLEN];
1250 if(!file->asset->vmpeg_progressive)
1252 sprintf(interlace_string, file->asset->vmpeg_field_order ? "b" : "t");
1256 sprintf(interlace_string, "p");
1259 fprintf(file->mjpeg_out, "YUV4MPEG2 W%d H%d F%d:%d I%s A%d:%d C%s\n",
1261 file->asset->height,
1262 (int)(file->asset->frame_rate * 1001),
1265 (int)(file->asset->aspect_ratio * 1000),
1270 // YUV4 frame header
1271 fprintf(file->mjpeg_out, "FRAME\n");
1274 if(!fwrite(file->mjpeg_y, file->asset->width * file->asset->height, 1, file->mjpeg_out))
1275 file->mjpeg_error = 1;
1276 if(!fwrite(file->mjpeg_u, file->asset->width * file->asset->height / 4, 1, file->mjpeg_out))
1277 file->mjpeg_error = 1;
1278 if(!fwrite(file->mjpeg_v, file->asset->width * file->asset->height / 4, 1, file->mjpeg_out))
1279 file->mjpeg_error = 1;
1280 fflush(file->mjpeg_out);
1282 file->next_frame_done->unlock();
1284 pclose(file->mjpeg_out);
1285 file->mjpeg_out = 0;
1308 FileMPEGAudio::FileMPEGAudio(FileMPEG *file)
1312 toolame_init_buffers();
1315 FileMPEGAudio::~FileMPEGAudio()
1320 void FileMPEGAudio::run()
1322 file->toolame_result = toolame(file->acommand_line.total, file->acommand_line.values);
1332 MPEGConfigAudio::MPEGConfigAudio(BC_WindowBase *parent_window, Asset *asset)
1333 : BC_Window(PROGRAM_NAME ": Audio Compression",
1334 parent_window->get_abs_cursor_x(1),
1335 parent_window->get_abs_cursor_y(1),
1344 this->parent_window = parent_window;
1345 this->asset = asset;
1348 MPEGConfigAudio::~MPEGConfigAudio()
1352 int MPEGConfigAudio::create_objects()
1358 add_tool(new BC_Title(x, y, _("Layer:")));
1359 add_tool(layer = new MPEGLayer(x1, y, this));
1360 layer->create_objects();
1363 add_tool(new BC_Title(x, y, _("Kbits per second:")));
1364 add_tool(bitrate = new MPEGABitrate(x1, y, this));
1365 bitrate->create_objects();
1368 add_subwindow(new BC_OKButton(this));
1374 int MPEGConfigAudio::close_event()
1386 MPEGLayer::MPEGLayer(int x, int y, MPEGConfigAudio *gui)
1387 : BC_PopupMenu(x, y, 100, layer_to_string(gui->asset->ampeg_derivative))
1392 void MPEGLayer::create_objects()
1394 add_item(new BC_MenuItem(layer_to_string(2)));
1395 add_item(new BC_MenuItem(layer_to_string(3)));
1398 int MPEGLayer::handle_event()
1400 gui->asset->ampeg_derivative = string_to_layer(get_text());
1401 gui->bitrate->set_layer(gui->asset->ampeg_derivative);
1405 int MPEGLayer::string_to_layer(char *string)
1407 if(!strcasecmp(layer_to_string(2), string))
1409 if(!strcasecmp(layer_to_string(3), string))
1415 char* MPEGLayer::layer_to_string(int layer)
1439 MPEGABitrate::MPEGABitrate(int x, int y, MPEGConfigAudio *gui)
1443 bitrate_to_string(gui->string, gui->asset->ampeg_bitrate))
1448 void MPEGABitrate::create_objects()
1450 set_layer(gui->asset->ampeg_derivative);
1453 void MPEGABitrate::set_layer(int layer)
1455 while(total_items())
1462 add_item(new BC_MenuItem("160"));
1463 add_item(new BC_MenuItem("192"));
1464 add_item(new BC_MenuItem("224"));
1465 add_item(new BC_MenuItem("256"));
1466 add_item(new BC_MenuItem("320"));
1467 add_item(new BC_MenuItem("384"));
1471 add_item(new BC_MenuItem("8"));
1472 add_item(new BC_MenuItem("16"));
1473 add_item(new BC_MenuItem("24"));
1474 add_item(new BC_MenuItem("32"));
1475 add_item(new BC_MenuItem("40"));
1476 add_item(new BC_MenuItem("48"));
1477 add_item(new BC_MenuItem("56"));
1478 add_item(new BC_MenuItem("64"));
1479 add_item(new BC_MenuItem("80"));
1480 add_item(new BC_MenuItem("96"));
1481 add_item(new BC_MenuItem("112"));
1482 add_item(new BC_MenuItem("128"));
1483 add_item(new BC_MenuItem("144"));
1484 add_item(new BC_MenuItem("160"));
1485 add_item(new BC_MenuItem("192"));
1486 add_item(new BC_MenuItem("224"));
1487 add_item(new BC_MenuItem("256"));
1488 add_item(new BC_MenuItem("320"));
1492 int MPEGABitrate::handle_event()
1494 gui->asset->ampeg_bitrate = string_to_bitrate(get_text());
1498 int MPEGABitrate::string_to_bitrate(char *string)
1500 return atol(string);
1504 char* MPEGABitrate::bitrate_to_string(char *string, int bitrate)
1506 sprintf(string, "%d", bitrate);
1518 MPEGConfigVideo::MPEGConfigVideo(BC_WindowBase *parent_window,
1520 : BC_Window(PROGRAM_NAME ": Video Compression",
1521 parent_window->get_abs_cursor_x(1),
1522 parent_window->get_abs_cursor_y(1),
1531 this->parent_window = parent_window;
1532 this->asset = asset;
1536 MPEGConfigVideo::~MPEGConfigVideo()
1540 int MPEGConfigVideo::create_objects()
1547 add_subwindow(new BC_Title(x, y, _("Color model:")));
1548 add_subwindow(cmodel = new MPEGColorModel(x1, y, this));
1549 cmodel->create_objects();
1552 update_cmodel_objs();
1554 add_subwindow(new BC_OKButton(this));
1560 int MPEGConfigVideo::close_event()
1567 void MPEGConfigVideo::delete_cmodel_objs()
1572 delete fixed_bitrate;
1575 delete iframe_distance;
1576 delete pframe_distance;
1577 delete top_field_first;
1581 titles.remove_all_objects();
1585 void MPEGConfigVideo::reset_cmodel()
1593 iframe_distance = 0;
1594 pframe_distance = 0;
1595 top_field_first = 0;
1601 void MPEGConfigVideo::update_cmodel_objs()
1609 delete_cmodel_objs();
1611 if(asset->vmpeg_cmodel == MPEG_YUV420)
1613 add_subwindow(title = new BC_Title(x, y + 5, _("Format Preset:")));
1614 titles.append(title);
1615 add_subwindow(preset = new MPEGPreset(x1, y, this));
1616 preset->create_objects();
1620 add_subwindow(title = new BC_Title(x, y + 5, _("Derivative:")));
1621 titles.append(title);
1622 add_subwindow(derivative = new MPEGDerivative(x1, y, this));
1623 derivative->create_objects();
1626 add_subwindow(title = new BC_Title(x, y + 5, _("Bitrate:")));
1627 titles.append(title);
1628 add_subwindow(bitrate = new MPEGBitrate(x1, y, this));
1629 add_subwindow(fixed_bitrate = new MPEGFixedBitrate(x2, y, this));
1632 add_subwindow(title = new BC_Title(x, y, _("Quantization:")));
1633 titles.append(title);
1634 quant = new MPEGQuant(x1, y, this);
1635 quant->create_objects();
1636 add_subwindow(fixed_quant = new MPEGFixedQuant(x2, y, this));
1639 add_subwindow(title = new BC_Title(x, y, _("I frame distance:")));
1640 titles.append(title);
1641 iframe_distance = new MPEGIFrameDistance(x1, y, this);
1642 iframe_distance->create_objects();
1645 if(asset->vmpeg_cmodel == MPEG_YUV420)
1647 add_subwindow(title = new BC_Title(x, y, _("P frame distance:")));
1648 titles.append(title);
1649 pframe_distance = new MPEGPFrameDistance(x1, y, this);
1650 pframe_distance->create_objects();
1653 add_subwindow(top_field_first = new BC_CheckBox(x, y, &asset->vmpeg_field_order, _("Bottom field first")));
1657 add_subwindow(progressive = new BC_CheckBox(x, y, &asset->vmpeg_progressive, _("Progressive frames")));
1659 add_subwindow(denoise = new BC_CheckBox(x, y, &asset->vmpeg_denoise, _("Denoise")));
1661 add_subwindow(seq_codes = new BC_CheckBox(x, y, &asset->vmpeg_seq_codes, _("Sequence start codes in every GOP")));
1677 MPEGDerivative::MPEGDerivative(int x, int y, MPEGConfigVideo *gui)
1678 : BC_PopupMenu(x, y, 150, derivative_to_string(gui->asset->vmpeg_derivative))
1683 void MPEGDerivative::create_objects()
1685 add_item(new BC_MenuItem(derivative_to_string(1)));
1686 add_item(new BC_MenuItem(derivative_to_string(2)));
1689 int MPEGDerivative::handle_event()
1691 gui->asset->vmpeg_derivative = string_to_derivative(get_text());
1695 int MPEGDerivative::string_to_derivative(char *string)
1697 if(!strcasecmp(derivative_to_string(1), string))
1699 if(!strcasecmp(derivative_to_string(2), string))
1705 char* MPEGDerivative::derivative_to_string(int derivative)
1733 MPEGPreset::MPEGPreset(int x, int y, MPEGConfigVideo *gui)
1734 : BC_PopupMenu(x, y, 200, value_to_string(gui->asset->vmpeg_preset))
1739 void MPEGPreset::create_objects()
1741 for(int i = 0; i < 10; i++)
1743 add_item(new BC_MenuItem(value_to_string(i)));
1747 int MPEGPreset::handle_event()
1749 gui->asset->vmpeg_preset = string_to_value(get_text());
1753 int MPEGPreset::string_to_value(char *string)
1755 for(int i = 0; i < 10; i++)
1757 if(!strcasecmp(value_to_string(i), string))
1763 char* MPEGPreset::value_to_string(int derivative)
1767 case 0: return _("Generic MPEG-1"); break;
1768 case 1: return _("standard VCD"); break;
1769 case 2: return _("user VCD"); break;
1770 case 3: return _("Generic MPEG-2"); break;
1771 case 4: return _("standard SVCD"); break;
1772 case 5: return _("user SVCD"); break;
1773 case 6: return _("VCD Still sequence"); break;
1774 case 7: return _("SVCD Still sequence"); break;
1775 case 8: return _("DVD NAV"); break;
1776 case 9: return _("DVD"); break;
1777 default: return _("Generic MPEG-1"); break;
1791 MPEGBitrate::MPEGBitrate(int x, int y, MPEGConfigVideo *gui)
1792 : BC_TextBox(x, y, 100, 1, gui->asset->vmpeg_bitrate)
1798 int MPEGBitrate::handle_event()
1800 gui->asset->vmpeg_bitrate = atol(get_text());
1808 MPEGQuant::MPEGQuant(int x, int y, MPEGConfigVideo *gui)
1809 : BC_TumbleTextBox(gui,
1810 (int64_t)gui->asset->vmpeg_quantization,
1820 int MPEGQuant::handle_event()
1822 gui->asset->vmpeg_quantization = atol(get_text());
1826 MPEGFixedBitrate::MPEGFixedBitrate(int x, int y, MPEGConfigVideo *gui)
1827 : BC_Radial(x, y, gui->asset->vmpeg_fix_bitrate, _("Fixed bitrate"))
1832 int MPEGFixedBitrate::handle_event()
1835 gui->asset->vmpeg_fix_bitrate = 1;
1836 gui->fixed_quant->update(0);
1840 MPEGFixedQuant::MPEGFixedQuant(int x, int y, MPEGConfigVideo *gui)
1841 : BC_Radial(x, y, !gui->asset->vmpeg_fix_bitrate, _("Fixed quantization"))
1846 int MPEGFixedQuant::handle_event()
1849 gui->asset->vmpeg_fix_bitrate = 0;
1850 gui->fixed_bitrate->update(0);
1862 MPEGIFrameDistance::MPEGIFrameDistance(int x, int y, MPEGConfigVideo *gui)
1863 : BC_TumbleTextBox(gui,
1864 (int64_t)gui->asset->vmpeg_iframe_distance,
1874 int MPEGIFrameDistance::handle_event()
1876 gui->asset->vmpeg_iframe_distance = atoi(get_text());
1886 MPEGPFrameDistance::MPEGPFrameDistance(int x, int y, MPEGConfigVideo *gui)
1887 : BC_TumbleTextBox(gui,
1888 (int64_t)gui->asset->vmpeg_pframe_distance,
1898 int MPEGPFrameDistance::handle_event()
1900 gui->asset->vmpeg_pframe_distance = atoi(get_text());
1911 MPEGColorModel::MPEGColorModel(int x, int y, MPEGConfigVideo *gui)
1912 : BC_PopupMenu(x, y, 150, cmodel_to_string(gui->asset->vmpeg_cmodel))
1917 void MPEGColorModel::create_objects()
1919 add_item(new BC_MenuItem(cmodel_to_string(0)));
1920 add_item(new BC_MenuItem(cmodel_to_string(1)));
1923 int MPEGColorModel::handle_event()
1925 gui->asset->vmpeg_cmodel = string_to_cmodel(get_text());
1926 gui->update_cmodel_objs();
1930 int MPEGColorModel::string_to_cmodel(char *string)
1932 if(!strcasecmp(cmodel_to_string(0), string))
1934 if(!strcasecmp(cmodel_to_string(1), string))
1939 char* MPEGColorModel::cmodel_to_string(int cmodel)
1944 return _("YUV 4:2:0");
1948 return _("YUV 4:2:2");
1952 return _("YUV 4:2:0");