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)
155 if(!(fd = mpeg3_open(asset->path, &error)))
157 printf("FileMPEG::open_file %s\n", asset->path);
162 // Determine if the file needs a table of contents and create one if needed.
163 if(!mpeg3_has_toc(fd))
165 // If it has video it must be scanned since video has keyframes.
166 if(mpeg3_total_vstreams(fd))
168 if(create_index()) return 1;
172 mpeg3_set_cpus(fd, file->cpus);
174 asset->audio_data = mpeg3_has_audio(fd);
175 if(asset->audio_data)
178 for(int i = 0; i < mpeg3_total_astreams(fd); i++)
180 asset->channels += mpeg3_audio_channels(fd, i);
182 if(!asset->sample_rate)
183 asset->sample_rate = mpeg3_sample_rate(fd, 0);
184 asset->audio_length = mpeg3_audio_samples(fd, 0);
187 asset->video_data = mpeg3_has_video(fd);
188 if(asset->video_data)
190 asset->layers = mpeg3_total_vstreams(fd);
191 asset->width = mpeg3_video_width(fd, 0);
192 asset->height = mpeg3_video_height(fd, 0);
193 asset->interlace_mode = BC_ILACE_MODE_UNDETECTED; // TODO: (to do this, start at hvirtualcvs/libmpeg3/headers.c
194 // and find out how to decode info from the header)
195 asset->video_length = mpeg3_video_frames(fd, 0);
196 asset->vmpeg_cmodel =
197 (mpeg3_colormodel(fd, 0) == MPEG3_YUV422P) ? MPEG_YUV422 : MPEG_YUV420;
198 if(!asset->frame_rate)
199 asset->frame_rate = mpeg3_frame_rate(fd, 0);
206 if(wr && asset->format == FILE_VMPEG)
208 // Heroine Virtual encoder
209 if(asset->vmpeg_cmodel == MPEG_YUV422)
211 char bitrate_string[BCTEXTLEN];
212 char quant_string[BCTEXTLEN];
213 char iframe_string[BCTEXTLEN];
215 sprintf(bitrate_string, "%d", asset->vmpeg_bitrate);
216 sprintf(quant_string, "%d", asset->vmpeg_quantization);
217 sprintf(iframe_string, "%d", asset->vmpeg_iframe_distance);
219 // Construct command line
222 append_vcommand_line("mpeg2enc");
225 if(asset->aspect_ratio > 0)
227 append_vcommand_line("-a");
228 if(EQUIV(asset->aspect_ratio, 1))
229 append_vcommand_line("1");
231 if(EQUIV(asset->aspect_ratio, 1.333))
232 append_vcommand_line("2");
234 if(EQUIV(asset->aspect_ratio, 1.777))
235 append_vcommand_line("3");
237 if(EQUIV(asset->aspect_ratio, 2.11))
238 append_vcommand_line("4");
241 append_vcommand_line(asset->vmpeg_derivative == 1 ? "-1" : "");
242 append_vcommand_line(asset->vmpeg_cmodel == MPEG_YUV422 ? "-422" : "");
243 if(asset->vmpeg_fix_bitrate)
245 append_vcommand_line("--cbr -b");
246 append_vcommand_line(bitrate_string);
250 append_vcommand_line("-q");
251 append_vcommand_line(quant_string);
253 append_vcommand_line(!asset->vmpeg_fix_bitrate ? quant_string : "");
254 append_vcommand_line("-n");
255 append_vcommand_line(iframe_string);
256 append_vcommand_line(asset->vmpeg_progressive ? "-p" : "");
257 append_vcommand_line(asset->vmpeg_denoise ? "-d" : "");
258 append_vcommand_line(file->cpus <= 1 ? "-u" : "");
259 append_vcommand_line(asset->vmpeg_seq_codes ? "-g" : "");
260 append_vcommand_line(asset->path);
262 video_out = new FileMPEGVideo(this);
267 // mjpegtools encoder
269 char string[BCTEXTLEN];
270 sprintf(mjpeg_command, MJPEG_EXE);
272 if(asset->vmpeg_fix_bitrate)
274 sprintf(string, " --cbr -b %d", asset->vmpeg_bitrate);
278 sprintf(string, " -q %d", asset->vmpeg_quantization);
280 strcat(mjpeg_command, string);
288 int aspect_ratio_code = -1;
289 if(asset->aspect_ratio > 0)
291 for(int i = 0; i < sizeof(aspect_ratio_codes) / sizeof(double); i++)
293 if(EQUIV(aspect_ratio_codes[i], asset->aspect_ratio))
295 aspect_ratio_code = i;
300 if(aspect_ratio_code < 0)
302 printf("FileMPEG::open_file: Unsupported aspect ratio %f\n", asset->aspect_ratio);
303 aspect_ratio_code = 2;
305 sprintf(string, " -a %d", aspect_ratio_code);
306 strcat(mjpeg_command, string);
314 int frame_rate_code = -1;
315 for(int i = 1; sizeof(frame_rate_codes) / sizeof(double); ++i)
317 if(EQUIV(asset->frame_rate, frame_rate_codes[i]))
323 if(frame_rate_code < 0)
326 printf("FileMPEG::open_file: Unsupported frame rate %f\n", asset->frame_rate);
328 sprintf(string, " -F %d", frame_rate_code);
329 strcat(mjpeg_command, string);
335 strcat(mjpeg_command,
336 asset->vmpeg_progressive ? " -I 0" : " -I 1");
340 sprintf(string, " -M %d", file->cpus);
341 strcat(mjpeg_command, string);
344 if(!asset->vmpeg_progressive)
346 strcat(mjpeg_command, asset->vmpeg_field_order ? " -z b" : " -z t");
350 sprintf(string, " -f %d", asset->vmpeg_preset);
351 strcat(mjpeg_command, string);
354 sprintf(string, " -g %d -G %d", asset->vmpeg_iframe_distance, asset->vmpeg_iframe_distance);
355 strcat(mjpeg_command, string);
358 if(asset->vmpeg_seq_codes) strcat(mjpeg_command, " -s");
361 sprintf(string, " -R %d", CLAMP(asset->vmpeg_pframe_distance, 0, 2));
362 strcat(mjpeg_command, string);
364 sprintf(string, " -o '%s'", asset->path);
365 strcat(mjpeg_command, string);
369 printf("FileMPEG::open_file: Running %s\n", mjpeg_command);
370 if(!(mjpeg_out = popen(mjpeg_command, "w")))
372 perror("FileMPEG::open_file");
375 video_out = new FileMPEGVideo(this);
380 if(wr && asset->format == FILE_AMPEG)
382 char command_line[BCTEXTLEN];
383 char encoder_string[BCTEXTLEN];
384 char argument_string[BCTEXTLEN];
386 //printf("FileMPEG::open_file 1 %d\n", asset->ampeg_derivative);
387 encoder_string[0] = 0;
389 if(asset->ampeg_derivative == 2)
391 char string[BCTEXTLEN];
392 append_acommand_line("toolame");
393 append_acommand_line("-m");
394 append_acommand_line((asset->channels >= 2) ? "j" : "m");
395 sprintf(string, "%f", (float)asset->sample_rate / 1000);
396 append_acommand_line("-s");
397 append_acommand_line(string);
398 sprintf(string, "%d", asset->ampeg_bitrate);
399 append_acommand_line("-b");
400 append_acommand_line(string);
401 append_acommand_line("-");
402 append_acommand_line(asset->path);
404 audio_out = new FileMPEGAudio(this);
408 if(asset->ampeg_derivative == 3)
410 lame_global = lame_init();
411 lame_set_brate(lame_global, asset->ampeg_bitrate / 1000);
412 lame_set_quality(lame_global, 0);
413 lame_set_in_samplerate(lame_global,
415 if((result = lame_init_params(lame_global)) < 0)
417 printf(_("encode: lame_init_params returned %d\n"), result);
418 lame_close(lame_global);
422 if(!(lame_fd = fopen(asset->path, "w")))
424 perror("FileMPEG::open_file");
425 lame_close(lame_global);
431 printf("FileMPEG::open_file: ampeg_derivative=%d\n", asset->ampeg_derivative);
448 int FileMPEG::create_index()
450 // Calculate TOC path
451 char index_filename[BCTEXTLEN];
452 char source_filename[BCTEXTLEN];
453 IndexFile::get_index_filename(source_filename,
454 file->preferences->index_directory,
457 char *ptr = strrchr(index_filename, '.');
462 sprintf(ptr, ".toc");
464 // Test existence of TOC
465 FILE *test = fopen(index_filename, "r");
468 // Reopen with table of contents
473 // Create progress window.
474 // This gets around the fact that MWindowGUI is locked.
475 char progress_title[BCTEXTLEN];
476 char string[BCTEXTLEN];
477 sprintf(progress_title, "Creating %s\n", index_filename);
479 mpeg3_t *index_file = mpeg3_start_toc(asset->path, index_filename, &total_bytes);
480 struct timeval new_time;
481 struct timeval prev_time;
482 struct timeval start_time;
483 struct timeval current_time;
484 gettimeofday(&prev_time, 0);
485 gettimeofday(&start_time, 0);
487 BC_ProgressBox *progress = new BC_ProgressBox(-1,
495 int64_t bytes_processed;
496 mpeg3_do_toc(index_file, &bytes_processed);
497 gettimeofday(&new_time, 0);
499 if(new_time.tv_sec - prev_time.tv_sec >= 1)
501 gettimeofday(¤t_time, 0);
502 int64_t elapsed_seconds = current_time.tv_sec - start_time.tv_sec;
503 int64_t total_seconds = elapsed_seconds * total_bytes / bytes_processed;
504 int64_t eta = total_seconds - elapsed_seconds;
505 progress->update(bytes_processed, 1);
511 progress->update_title(string, 1);
512 // fprintf(stderr, "ETA: %dm%ds \r",
513 // bytes_processed * 100 / total_bytes,
517 prev_time = new_time;
519 if(bytes_processed >= total_bytes) break;
520 if(progress->is_cancelled())
527 mpeg3_stop_toc(index_file);
529 progress->stop_progress();
535 remove(index_filename);
539 // Fix date to date of source if success
547 // Reopen file from index path instead of asset path.
548 if(fd) mpeg3_close(fd);
549 if(!(fd = mpeg3_open(index_filename, &error)))
562 void FileMPEG::append_vcommand_line(const char *string)
566 char *argv = strdup(string);
567 vcommand_line.append(argv);
571 void FileMPEG::append_acommand_line(const char *string)
575 char *argv = strdup(string);
576 acommand_line.append(argv);
581 int FileMPEG::close_file()
584 next_frame_lock->unlock();
593 // End of sequence signal
594 if(file->asset->vmpeg_cmodel == MPEG_YUV422)
596 mpeg2enc_set_input_buffers(1, 0, 0, 0);
602 vcommand_line.remove_all_objects();
603 acommand_line.remove_all_objects();
607 toolame_send_buffer(0, 0);
613 lame_close(lame_global);
615 if(temp_frame) delete temp_frame;
616 if(toolame_temp) delete [] toolame_temp;
618 if(lame_temp[0]) delete [] lame_temp[0];
619 if(lame_temp[1]) delete [] lame_temp[1];
620 if(lame_output) delete [] lame_output;
621 if(lame_fd) fclose(lame_fd);
623 if(mjpeg_out) fclose(mjpeg_out);
626 FileBase::close_file();
630 int FileMPEG::get_best_colormodel(Asset *asset, int driver)
632 //printf("FileMPEG::get_best_colormodel 1\n");
637 if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
638 if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
640 case PLAYBACK_X11_XV:
641 if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
642 if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
648 case PLAYBACK_DV1394:
649 case PLAYBACK_FIREWIRE:
654 if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
655 if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
661 case CAPTURE_FIREWIRE:
662 case CAPTURE_IEC61883:
666 //printf("FileMPEG::get_best_colormodel 100\n");
669 int FileMPEG::colormodel_supported(int colormodel)
674 int FileMPEG::get_index(char *index_path)
679 // Convert the index tables from tracks to channels.
680 if(mpeg3_index_tracks(fd))
682 // Calculate size of buffer needed for all channels
684 for(int i = 0; i < mpeg3_index_tracks(fd); i++)
686 buffer_size += mpeg3_index_size(fd, i) *
687 mpeg3_index_channels(fd, i) *
691 asset->index_buffer = new float[buffer_size];
693 // Size of index buffer in floats
694 int current_offset = 0;
695 // Current asset channel
696 int current_channel = 0;
697 asset->index_zoom = mpeg3_index_zoom(fd);
698 asset->index_offsets = new int64_t[asset->channels];
699 asset->index_sizes = new int64_t[asset->channels];
700 for(int i = 0; i < mpeg3_index_tracks(fd); i++)
702 for(int j = 0; j < mpeg3_index_channels(fd, i); j++)
704 asset->index_offsets[current_channel] = current_offset;
705 asset->index_sizes[current_channel] = mpeg3_index_size(fd, i) * 2;
706 memcpy(asset->index_buffer + current_offset,
707 mpeg3_index_data(fd, i, j),
708 mpeg3_index_size(fd, i) * sizeof(float) * 2);
710 current_offset += mpeg3_index_size(fd, i) * 2;
716 asset->index_bytes = fs.get_size(asset->path);
718 asset->write_index(index_path, buffer_size * sizeof(float));
719 delete [] asset->index_buffer;
728 int FileMPEG::can_copy_from(Edit *edit, int64_t position)
734 int FileMPEG::set_audio_position(int64_t sample)
740 to_streamchannel(file->current_channel, stream, channel);
742 //printf("FileMPEG::set_audio_position %d %d %d\n", sample, mpeg3_get_sample(fd, stream), last_sample);
743 if(sample != mpeg3_get_sample(fd, stream) &&
744 sample != last_sample)
746 if(sample >= 0 && sample < asset->audio_length)
748 //printf("FileMPEG::set_audio_position seeking stream %d\n", sample);
749 return mpeg3_set_sample(fd, sample, stream);
758 int FileMPEG::set_video_position(int64_t x)
761 if(x >= 0 && x < asset->video_length)
763 //printf("FileMPEG::set_video_position 1 %lld\n", x);
764 mpeg3_set_frame(fd, x, file->current_layer);
770 int64_t FileMPEG::get_memory_usage()
774 int64_t result = mpeg3_memory_usage(fd);
781 int FileMPEG::write_samples(double **buffer, int64_t len)
785 //printf("FileMPEG::write_samples 1\n");
786 if(asset->ampeg_derivative == 2)
789 int channels = MIN(asset->channels, 2);
790 int64_t audio_size = len * channels * 2;
791 if(toolame_allocation < audio_size)
793 if(toolame_temp) delete [] toolame_temp;
794 toolame_temp = new unsigned char[audio_size];
795 toolame_allocation = audio_size;
798 for(int i = 0; i < channels; i++)
800 int16_t *output = ((int16_t*)toolame_temp) + i;
801 double *input = buffer[i];
802 for(int j = 0; j < len; j++)
804 int sample = (int)(*input * 0x7fff);
805 *output = (int16_t)(CLIP(sample, -0x8000, 0x7fff));
810 result = toolame_send_buffer((char*)toolame_temp, audio_size);
813 if(asset->ampeg_derivative == 3)
815 int channels = MIN(asset->channels, 2);
816 int64_t audio_size = len * channels;
817 if(!lame_global) return 1;
818 if(!lame_fd) return 1;
819 if(lame_allocation < audio_size)
821 if(lame_temp[0]) delete [] lame_temp[0];
822 if(lame_temp[1]) delete [] lame_temp[1];
823 lame_temp[0] = new float[audio_size];
824 lame_temp[1] = new float[audio_size];
825 lame_allocation = audio_size;
828 if(lame_output_allocation < audio_size * 4)
830 if(lame_output) delete [] lame_output;
831 lame_output_allocation = audio_size * 4;
832 lame_output = new char[lame_output_allocation];
835 for(int i = 0; i < channels; i++)
837 float *output = lame_temp[i];
838 double *input = buffer[i];
839 for(int j = 0; j < len; j++)
841 *output++ = *input++ * (float)32768;
845 result = lame_encode_buffer_float(lame_global,
847 (channels > 1) ? lame_temp[1] : lame_temp[0],
849 (unsigned char*)lame_output,
850 lame_output_allocation);
853 char *real_output = lame_output;
857 for(int i = 0; i < bytes; i++)
860 real_output = &lame_output[i];
866 if(bytes > 0 && lame_started)
868 result = !fwrite(real_output, 1, bytes, lame_fd);
870 perror("FileMPEG::write_samples");
882 int FileMPEG::write_frames(VFrame ***frames, int len)
888 int temp_w = (int)((asset->width + 15) / 16) * 16;
893 (asset->vmpeg_cmodel == MPEG_YUV420) ? BC_YUV420P : BC_YUV422P;
896 // Height depends on progressiveness
897 if(asset->vmpeg_progressive || asset->vmpeg_derivative == 1)
898 temp_h = (int)((asset->height + 15) / 16) * 16;
900 temp_h = (int)((asset->height + 31) / 32) * 32;
902 //printf("FileMPEG::write_frames 1\n");
904 // Only 1 layer is supported in MPEG output
905 for(int i = 0; i < 1; i++)
907 for(int j = 0; j < len && !result; j++)
909 VFrame *frame = frames[i][j];
913 if(asset->vmpeg_cmodel == MPEG_YUV422)
915 if(frame->get_w() == temp_w &&
916 frame->get_h() == temp_h &&
917 frame->get_color_model() == output_cmodel)
919 mpeg2enc_set_input_buffers(0,
920 (char*)frame->get_y(),
921 (char*)frame->get_u(),
922 (char*)frame->get_v());
927 (temp_frame->get_w() != temp_w ||
928 temp_frame->get_h() != temp_h ||
929 temp_frame->get_color_model() || output_cmodel))
938 temp_frame = new VFrame(0,
944 cmodel_transfer(temp_frame->get_rows(),
960 frame->get_color_model(),
961 temp_frame->get_color_model(),
966 mpeg2enc_set_input_buffers(0,
967 (char*)temp_frame->get_y(),
968 (char*)temp_frame->get_u(),
969 (char*)temp_frame->get_v());
974 // MJPEG uses the same dimensions as the input
975 if(frame->get_color_model() == output_cmodel)
977 mjpeg_y = frame->get_y();
978 mjpeg_u = frame->get_u();
979 mjpeg_v = frame->get_v();
985 temp_frame = new VFrame(0,
991 cmodel_transfer(temp_frame->get_rows(),
1007 frame->get_color_model(),
1008 temp_frame->get_color_model(),
1013 mjpeg_y = temp_frame->get_y();
1014 mjpeg_u = temp_frame->get_u();
1015 mjpeg_v = temp_frame->get_v();
1021 next_frame_lock->unlock();
1022 next_frame_done->lock("FileMPEG::write_frames");
1023 if(mjpeg_error) result = 1;
1039 int FileMPEG::read_frame(VFrame *frame)
1045 // printf("FileMPEG::read_frame\n");
1046 // frame->dump_stacks();
1047 // frame->dump_params();
1049 if(mpeg3_colormodel(fd, 0) == MPEG3_YUV420P)
1050 src_cmodel = BC_YUV420P;
1052 if(mpeg3_colormodel(fd, 0) == MPEG3_YUV422P)
1053 src_cmodel = BC_YUV422P;
1055 switch(frame->get_color_model())
1059 case MPEG3_BGRA8888:
1061 case MPEG3_RGBA8888:
1062 case MPEG3_RGBA16161616:
1064 mpeg3_read_frame(fd,
1065 frame->get_rows(), /* Array of pointers to the start of each output row */
1066 0, /* Location in input frame to take picture */
1070 asset->width, /* Dimensions of output_rows */
1072 frame->get_color_model(), /* One of the color model #defines */
1073 file->current_layer);
1079 // Read these directly
1080 if(frame->get_color_model() == src_cmodel)
1083 mpeg3_read_yuvframe(fd,
1084 (char*)frame->get_y(),
1085 (char*)frame->get_u(),
1086 (char*)frame->get_v(),
1091 file->current_layer);
1095 // Process through temp frame
1099 mpeg3_read_yuvframe_ptr(fd,
1103 file->current_layer);
1107 cmodel_transfer(frame->get_rows(),
1124 frame->get_color_model(),
1138 void FileMPEG::to_streamchannel(int channel, int &stream_out, int &channel_out)
1140 for(stream_out = 0, channel_out = file->current_channel;
1141 stream_out < mpeg3_total_astreams(fd) &&
1142 channel_out >= mpeg3_audio_channels(fd, stream_out);
1143 channel_out -= mpeg3_audio_channels(fd, stream_out), stream_out++)
1147 int FileMPEG::read_samples(double *buffer, int64_t len)
1150 if(len < 0) return 0;
1152 // This is directed to a FileMPEGBuffer
1153 float *temp_float = new float[len];
1154 // Translate pure channel to a stream and a channel in the mpeg stream
1155 int stream, channel;
1156 to_streamchannel(file->current_channel, stream, channel);
1160 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
1162 mpeg3_set_sample(fd,
1163 file->current_sample,
1165 mpeg3_read_audio(fd,
1166 temp_float, /* Pointer to pre-allocated buffer of floats */
1167 0, /* Pointer to pre-allocated buffer of int16's */
1168 channel, /* Channel to decode */
1169 len, /* Number of samples to decode */
1170 stream); /* Stream containing the channel */
1173 // last_sample = file->current_sample;
1174 for(int i = 0; i < len; i++) buffer[i] = temp_float[i];
1176 delete [] temp_float;
1180 int FileMPEG::prefer_samples_float()
1185 int FileMPEG::read_samples_float(float *buffer, int64_t len)
1189 // Translate pure channel to a stream and a channel in the mpeg stream
1190 int stream, channel;
1191 to_streamchannel(file->current_channel, stream, channel);
1194 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
1196 mpeg3_set_sample(fd,
1197 file->current_sample,
1199 mpeg3_read_audio(fd,
1200 buffer, /* Pointer to pre-allocated buffer of floats */
1201 0, /* Pointer to pre-allocated buffer of int16's */
1202 channel, /* Channel to decode */
1203 len, /* Number of samples to decode */
1204 stream); /* Stream containing the channel */
1207 // last_sample = file->current_sample;
1209 //printf("FileMPEG::read_samples 100\n");
1215 char* FileMPEG::strtocompression(char *string)
1220 char* FileMPEG::compressiontostr(char *string)
1231 FileMPEGVideo::FileMPEGVideo(FileMPEG *file)
1237 if(file->asset->vmpeg_cmodel == MPEG_YUV422)
1239 mpeg2enc_init_buffers();
1240 mpeg2enc_set_w(file->asset->width);
1241 mpeg2enc_set_h(file->asset->height);
1242 mpeg2enc_set_rate(file->asset->frame_rate);
1246 FileMPEGVideo::~FileMPEGVideo()
1251 void FileMPEGVideo::run()
1253 if(file->asset->vmpeg_cmodel == MPEG_YUV422)
1255 printf("FileMPEGVideo::run ");
1256 for(int i = 0; i < file->vcommand_line.total; i++)
1257 printf("%s ", file->vcommand_line.values[i]);
1259 mpeg2enc(file->vcommand_line.total, file->vcommand_line.values);
1265 file->next_frame_lock->lock("FileMPEGVideo::run");
1268 file->next_frame_done->unlock();
1274 // YUV4 sequence header
1275 if(!file->wrote_header)
1277 file->wrote_header = 1;
1279 char string[BCTEXTLEN];
1280 char interlace_string[BCTEXTLEN];
1281 if(!file->asset->vmpeg_progressive)
1283 sprintf(interlace_string, file->asset->vmpeg_field_order ? "b" : "t");
1287 sprintf(interlace_string, "p");
1290 fprintf(file->mjpeg_out, "YUV4MPEG2 W%d H%d F%d:%d I%s A%d:%d C%s\n",
1292 file->asset->height,
1293 (int)(file->asset->frame_rate * 1001),
1296 (int)(file->asset->aspect_ratio * 1000),
1301 // YUV4 frame header
1302 fprintf(file->mjpeg_out, "FRAME\n");
1305 if(!fwrite(file->mjpeg_y, file->asset->width * file->asset->height, 1, file->mjpeg_out))
1306 file->mjpeg_error = 1;
1307 if(!fwrite(file->mjpeg_u, file->asset->width * file->asset->height / 4, 1, file->mjpeg_out))
1308 file->mjpeg_error = 1;
1309 if(!fwrite(file->mjpeg_v, file->asset->width * file->asset->height / 4, 1, file->mjpeg_out))
1310 file->mjpeg_error = 1;
1311 fflush(file->mjpeg_out);
1313 file->next_frame_done->unlock();
1315 pclose(file->mjpeg_out);
1316 file->mjpeg_out = 0;
1339 FileMPEGAudio::FileMPEGAudio(FileMPEG *file)
1343 toolame_init_buffers();
1346 FileMPEGAudio::~FileMPEGAudio()
1351 void FileMPEGAudio::run()
1353 file->toolame_result = toolame(file->acommand_line.total, file->acommand_line.values);
1363 MPEGConfigAudio::MPEGConfigAudio(BC_WindowBase *parent_window, Asset *asset)
1364 : BC_Window(PROGRAM_NAME ": Audio Compression",
1365 parent_window->get_abs_cursor_x(1),
1366 parent_window->get_abs_cursor_y(1),
1375 this->parent_window = parent_window;
1376 this->asset = asset;
1379 MPEGConfigAudio::~MPEGConfigAudio()
1383 int MPEGConfigAudio::create_objects()
1389 add_tool(new BC_Title(x, y, _("Layer:")));
1390 add_tool(layer = new MPEGLayer(x1, y, this));
1391 layer->create_objects();
1394 add_tool(new BC_Title(x, y, _("Kbits per second:")));
1395 add_tool(bitrate = new MPEGABitrate(x1, y, this));
1396 bitrate->create_objects();
1399 add_subwindow(new BC_OKButton(this));
1405 int MPEGConfigAudio::close_event()
1417 MPEGLayer::MPEGLayer(int x, int y, MPEGConfigAudio *gui)
1418 : BC_PopupMenu(x, y, 100, layer_to_string(gui->asset->ampeg_derivative))
1423 void MPEGLayer::create_objects()
1425 add_item(new BC_MenuItem(layer_to_string(2)));
1426 add_item(new BC_MenuItem(layer_to_string(3)));
1429 int MPEGLayer::handle_event()
1431 gui->asset->ampeg_derivative = string_to_layer(get_text());
1432 gui->bitrate->set_layer(gui->asset->ampeg_derivative);
1436 int MPEGLayer::string_to_layer(char *string)
1438 if(!strcasecmp(layer_to_string(2), string))
1440 if(!strcasecmp(layer_to_string(3), string))
1446 char* MPEGLayer::layer_to_string(int layer)
1470 MPEGABitrate::MPEGABitrate(int x, int y, MPEGConfigAudio *gui)
1474 bitrate_to_string(gui->string, gui->asset->ampeg_bitrate))
1479 void MPEGABitrate::create_objects()
1481 set_layer(gui->asset->ampeg_derivative);
1484 void MPEGABitrate::set_layer(int layer)
1486 while(total_items())
1493 add_item(new BC_MenuItem("160"));
1494 add_item(new BC_MenuItem("192"));
1495 add_item(new BC_MenuItem("224"));
1496 add_item(new BC_MenuItem("256"));
1497 add_item(new BC_MenuItem("320"));
1498 add_item(new BC_MenuItem("384"));
1502 add_item(new BC_MenuItem("8"));
1503 add_item(new BC_MenuItem("16"));
1504 add_item(new BC_MenuItem("24"));
1505 add_item(new BC_MenuItem("32"));
1506 add_item(new BC_MenuItem("40"));
1507 add_item(new BC_MenuItem("48"));
1508 add_item(new BC_MenuItem("56"));
1509 add_item(new BC_MenuItem("64"));
1510 add_item(new BC_MenuItem("80"));
1511 add_item(new BC_MenuItem("96"));
1512 add_item(new BC_MenuItem("112"));
1513 add_item(new BC_MenuItem("128"));
1514 add_item(new BC_MenuItem("144"));
1515 add_item(new BC_MenuItem("160"));
1516 add_item(new BC_MenuItem("192"));
1517 add_item(new BC_MenuItem("224"));
1518 add_item(new BC_MenuItem("256"));
1519 add_item(new BC_MenuItem("320"));
1523 int MPEGABitrate::handle_event()
1525 gui->asset->ampeg_bitrate = string_to_bitrate(get_text());
1529 int MPEGABitrate::string_to_bitrate(char *string)
1531 return atol(string);
1535 char* MPEGABitrate::bitrate_to_string(char *string, int bitrate)
1537 sprintf(string, "%d", bitrate);
1549 MPEGConfigVideo::MPEGConfigVideo(BC_WindowBase *parent_window,
1551 : BC_Window(PROGRAM_NAME ": Video Compression",
1552 parent_window->get_abs_cursor_x(1),
1553 parent_window->get_abs_cursor_y(1),
1562 this->parent_window = parent_window;
1563 this->asset = asset;
1567 MPEGConfigVideo::~MPEGConfigVideo()
1571 int MPEGConfigVideo::create_objects()
1578 add_subwindow(new BC_Title(x, y, _("Color model:")));
1579 add_subwindow(cmodel = new MPEGColorModel(x1, y, this));
1580 cmodel->create_objects();
1583 update_cmodel_objs();
1585 add_subwindow(new BC_OKButton(this));
1591 int MPEGConfigVideo::close_event()
1598 void MPEGConfigVideo::delete_cmodel_objs()
1603 delete fixed_bitrate;
1606 delete iframe_distance;
1607 delete pframe_distance;
1608 delete top_field_first;
1612 titles.remove_all_objects();
1616 void MPEGConfigVideo::reset_cmodel()
1624 iframe_distance = 0;
1625 pframe_distance = 0;
1626 top_field_first = 0;
1632 void MPEGConfigVideo::update_cmodel_objs()
1640 delete_cmodel_objs();
1642 if(asset->vmpeg_cmodel == MPEG_YUV420)
1644 add_subwindow(title = new BC_Title(x, y + 5, _("Format Preset:")));
1645 titles.append(title);
1646 add_subwindow(preset = new MPEGPreset(x1, y, this));
1647 preset->create_objects();
1651 add_subwindow(title = new BC_Title(x, y + 5, _("Derivative:")));
1652 titles.append(title);
1653 add_subwindow(derivative = new MPEGDerivative(x1, y, this));
1654 derivative->create_objects();
1657 add_subwindow(title = new BC_Title(x, y + 5, _("Bitrate:")));
1658 titles.append(title);
1659 add_subwindow(bitrate = new MPEGBitrate(x1, y, this));
1660 add_subwindow(fixed_bitrate = new MPEGFixedBitrate(x2, y, this));
1663 add_subwindow(title = new BC_Title(x, y, _("Quantization:")));
1664 titles.append(title);
1665 quant = new MPEGQuant(x1, y, this);
1666 quant->create_objects();
1667 add_subwindow(fixed_quant = new MPEGFixedQuant(x2, y, this));
1670 add_subwindow(title = new BC_Title(x, y, _("I frame distance:")));
1671 titles.append(title);
1672 iframe_distance = new MPEGIFrameDistance(x1, y, this);
1673 iframe_distance->create_objects();
1676 if(asset->vmpeg_cmodel == MPEG_YUV420)
1678 add_subwindow(title = new BC_Title(x, y, _("P frame distance:")));
1679 titles.append(title);
1680 pframe_distance = new MPEGPFrameDistance(x1, y, this);
1681 pframe_distance->create_objects();
1684 add_subwindow(top_field_first = new BC_CheckBox(x, y, &asset->vmpeg_field_order, _("Bottom field first")));
1688 add_subwindow(progressive = new BC_CheckBox(x, y, &asset->vmpeg_progressive, _("Progressive frames")));
1690 add_subwindow(denoise = new BC_CheckBox(x, y, &asset->vmpeg_denoise, _("Denoise")));
1692 add_subwindow(seq_codes = new BC_CheckBox(x, y, &asset->vmpeg_seq_codes, _("Sequence start codes in every GOP")));
1708 MPEGDerivative::MPEGDerivative(int x, int y, MPEGConfigVideo *gui)
1709 : BC_PopupMenu(x, y, 150, derivative_to_string(gui->asset->vmpeg_derivative))
1714 void MPEGDerivative::create_objects()
1716 add_item(new BC_MenuItem(derivative_to_string(1)));
1717 add_item(new BC_MenuItem(derivative_to_string(2)));
1720 int MPEGDerivative::handle_event()
1722 gui->asset->vmpeg_derivative = string_to_derivative(get_text());
1726 int MPEGDerivative::string_to_derivative(char *string)
1728 if(!strcasecmp(derivative_to_string(1), string))
1730 if(!strcasecmp(derivative_to_string(2), string))
1736 char* MPEGDerivative::derivative_to_string(int derivative)
1764 MPEGPreset::MPEGPreset(int x, int y, MPEGConfigVideo *gui)
1765 : BC_PopupMenu(x, y, 200, value_to_string(gui->asset->vmpeg_preset))
1770 void MPEGPreset::create_objects()
1772 for(int i = 0; i < 10; i++)
1774 add_item(new BC_MenuItem(value_to_string(i)));
1778 int MPEGPreset::handle_event()
1780 gui->asset->vmpeg_preset = string_to_value(get_text());
1784 int MPEGPreset::string_to_value(char *string)
1786 for(int i = 0; i < 10; i++)
1788 if(!strcasecmp(value_to_string(i), string))
1794 char* MPEGPreset::value_to_string(int derivative)
1798 case 0: return _("Generic MPEG-1"); break;
1799 case 1: return _("standard VCD"); break;
1800 case 2: return _("user VCD"); break;
1801 case 3: return _("Generic MPEG-2"); break;
1802 case 4: return _("standard SVCD"); break;
1803 case 5: return _("user SVCD"); break;
1804 case 6: return _("VCD Still sequence"); break;
1805 case 7: return _("SVCD Still sequence"); break;
1806 case 8: return _("DVD NAV"); break;
1807 case 9: return _("DVD"); break;
1808 default: return _("Generic MPEG-1"); break;
1822 MPEGBitrate::MPEGBitrate(int x, int y, MPEGConfigVideo *gui)
1823 : BC_TextBox(x, y, 100, 1, gui->asset->vmpeg_bitrate)
1829 int MPEGBitrate::handle_event()
1831 gui->asset->vmpeg_bitrate = atol(get_text());
1839 MPEGQuant::MPEGQuant(int x, int y, MPEGConfigVideo *gui)
1840 : BC_TumbleTextBox(gui,
1841 (int64_t)gui->asset->vmpeg_quantization,
1851 int MPEGQuant::handle_event()
1853 gui->asset->vmpeg_quantization = atol(get_text());
1857 MPEGFixedBitrate::MPEGFixedBitrate(int x, int y, MPEGConfigVideo *gui)
1858 : BC_Radial(x, y, gui->asset->vmpeg_fix_bitrate, _("Fixed bitrate"))
1863 int MPEGFixedBitrate::handle_event()
1866 gui->asset->vmpeg_fix_bitrate = 1;
1867 gui->fixed_quant->update(0);
1871 MPEGFixedQuant::MPEGFixedQuant(int x, int y, MPEGConfigVideo *gui)
1872 : BC_Radial(x, y, !gui->asset->vmpeg_fix_bitrate, _("Fixed quantization"))
1877 int MPEGFixedQuant::handle_event()
1880 gui->asset->vmpeg_fix_bitrate = 0;
1881 gui->fixed_bitrate->update(0);
1893 MPEGIFrameDistance::MPEGIFrameDistance(int x, int y, MPEGConfigVideo *gui)
1894 : BC_TumbleTextBox(gui,
1895 (int64_t)gui->asset->vmpeg_iframe_distance,
1905 int MPEGIFrameDistance::handle_event()
1907 gui->asset->vmpeg_iframe_distance = atoi(get_text());
1917 MPEGPFrameDistance::MPEGPFrameDistance(int x, int y, MPEGConfigVideo *gui)
1918 : BC_TumbleTextBox(gui,
1919 (int64_t)gui->asset->vmpeg_pframe_distance,
1929 int MPEGPFrameDistance::handle_event()
1931 gui->asset->vmpeg_pframe_distance = atoi(get_text());
1942 MPEGColorModel::MPEGColorModel(int x, int y, MPEGConfigVideo *gui)
1943 : BC_PopupMenu(x, y, 150, cmodel_to_string(gui->asset->vmpeg_cmodel))
1948 void MPEGColorModel::create_objects()
1950 add_item(new BC_MenuItem(cmodel_to_string(0)));
1951 add_item(new BC_MenuItem(cmodel_to_string(1)));
1954 int MPEGColorModel::handle_event()
1956 gui->asset->vmpeg_cmodel = string_to_cmodel(get_text());
1957 gui->update_cmodel_objs();
1961 int MPEGColorModel::string_to_cmodel(char *string)
1963 if(!strcasecmp(cmodel_to_string(0), string))
1965 if(!strcasecmp(cmodel_to_string(1), string))
1970 char* MPEGColorModel::cmodel_to_string(int cmodel)
1975 return _("YUV 4:2:0");
1979 return _("YUV 4:2:2");
1983 return _("YUV 4:2:0");