2 #include "bcprogressbox.h"
11 #include "filesystem.h"
13 #include "indexfile.h"
14 #include "interlacemodes.h"
16 #include "mainerror.h"
17 #include "mwindow.inc"
18 #include "preferences.h"
20 #include "videodevice.inc"
30 #define MJPEG_EXE PLUGIN_DIR "/mpeg2enc.plugin"
38 // M JPEG dependancies
39 static double frame_rate_codes[] =
52 static double aspect_ratio_codes[] =
68 FileMPEG::FileMPEG(Asset *asset, File *file)
69 : FileBase(asset, file)
72 // May also be VMPEG or AMPEG if write status.
73 if(asset->format == FILE_UNKNOWN) asset->format = FILE_MPEG;
74 asset->byte_order = 0;
75 next_frame_lock = new Condition(0, "FileMPEG::next_frame_lock");
76 next_frame_done = new Condition(0, "FileMPEG::next_frame_done");
82 delete next_frame_lock;
83 delete next_frame_done;
86 void FileMPEG::get_parameters(BC_WindowBase *parent_window,
88 BC_WindowBase* &format_window,
92 if(audio_options && asset->format == FILE_AMPEG)
94 MPEGConfigAudio *window = new MPEGConfigAudio(parent_window, asset);
95 format_window = window;
96 window->create_objects();
101 if(video_options && asset->format == FILE_VMPEG)
103 MPEGConfigVideo *window = new MPEGConfigVideo(parent_window, asset);
104 format_window = window;
105 window->create_objects();
106 window->run_window();
111 int FileMPEG::check_sig(Asset *asset)
113 return mpeg3_check_sig(asset->path);
116 void FileMPEG::get_info(Asset *asset, int64_t *bytes, int *stracks)
121 if((fd = mpeg3_open(asset->path, &error)))
123 *bytes = mpeg3_get_bytes(fd);
124 *stracks = mpeg3_subtitle_tracks(fd);
130 int FileMPEG::reset_parameters_derived()
147 toolame_allocation = 0;
154 lame_output_allocation = 0;
160 // Just create the Quicktime objects since this routine is also called
162 int FileMPEG::open_file(int rd, int wr)
172 if(!(fd = mpeg3_open(asset->path, &error)))
174 char string[BCTEXTLEN];
175 if(error == MPEG3_INVALID_TOC_VERSION)
177 eprintf("Couldn't open %s because it has an invalid table of contents version.\n"
178 "Rebuild the table of contents with mpeg3toc.",
182 if(error == MPEG3_TOC_DATE_MISMATCH)
184 eprintf("Couldn't open %s because the table of contents date differs from the source date.\n"
185 "Rebuild the table of contents with mpeg3toc.",
192 // Determine if the file needs a table of contents and create one if needed.
193 // If it has video it must be scanned since video has keyframes.
194 if(mpeg3_total_vstreams(fd))
196 if(create_index()) return 1;
199 mpeg3_set_cpus(fd, file->cpus);
201 asset->audio_data = mpeg3_has_audio(fd);
202 if(asset->audio_data)
205 for(int i = 0; i < mpeg3_total_astreams(fd); i++)
207 asset->channels += mpeg3_audio_channels(fd, i);
209 if(!asset->sample_rate)
210 asset->sample_rate = mpeg3_sample_rate(fd, 0);
211 asset->audio_length = mpeg3_audio_samples(fd, 0);
214 asset->video_data = mpeg3_has_video(fd);
215 if(asset->video_data)
217 asset->layers = mpeg3_total_vstreams(fd);
218 asset->width = mpeg3_video_width(fd, 0);
219 asset->height = mpeg3_video_height(fd, 0);
220 asset->interlace_mode = BC_ILACE_MODE_UNDETECTED; // TODO: (to do this, start at hvirtualcvs/libmpeg3/headers.c
221 // and find out how to decode info from the header)
222 asset->video_length = mpeg3_video_frames(fd, 0);
223 asset->vmpeg_cmodel =
224 (mpeg3_colormodel(fd, 0) == MPEG3_YUV422P) ? MPEG_YUV422 : MPEG_YUV420;
225 if(!asset->frame_rate)
226 asset->frame_rate = mpeg3_frame_rate(fd, 0);
229 //printf("FileMPEG::open %d\n", file->playback_subtitle);
230 if(file->playback_subtitle >= 0)
231 mpeg3_show_subtitle(fd, file->playback_subtitle);
238 if(wr && asset->format == FILE_VMPEG)
240 // Heroine Virtual encoder
241 if(asset->vmpeg_cmodel == MPEG_YUV422)
243 char bitrate_string[BCTEXTLEN];
244 char quant_string[BCTEXTLEN];
245 char iframe_string[BCTEXTLEN];
247 sprintf(bitrate_string, "%d", asset->vmpeg_bitrate);
248 sprintf(quant_string, "%d", asset->vmpeg_quantization);
249 sprintf(iframe_string, "%d", asset->vmpeg_iframe_distance);
251 // Construct command line
254 append_vcommand_line("mpeg2enc");
257 if(asset->aspect_ratio > 0)
259 append_vcommand_line("-a");
260 if(EQUIV(asset->aspect_ratio, 1))
261 append_vcommand_line("1");
263 if(EQUIV(asset->aspect_ratio, 1.333))
264 append_vcommand_line("2");
266 if(EQUIV(asset->aspect_ratio, 1.777))
267 append_vcommand_line("3");
269 if(EQUIV(asset->aspect_ratio, 2.11))
270 append_vcommand_line("4");
273 append_vcommand_line(asset->vmpeg_derivative == 1 ? "-1" : "");
274 append_vcommand_line(asset->vmpeg_cmodel == MPEG_YUV422 ? "-422" : "");
275 if(asset->vmpeg_fix_bitrate)
277 append_vcommand_line("--cbr -b");
278 append_vcommand_line(bitrate_string);
282 append_vcommand_line("-q");
283 append_vcommand_line(quant_string);
285 append_vcommand_line(!asset->vmpeg_fix_bitrate ? quant_string : "");
286 append_vcommand_line("-n");
287 append_vcommand_line(iframe_string);
288 append_vcommand_line(asset->vmpeg_progressive ? "-p" : "");
289 append_vcommand_line(asset->vmpeg_denoise ? "-d" : "");
290 append_vcommand_line(file->cpus <= 1 ? "-u" : "");
291 append_vcommand_line(asset->vmpeg_seq_codes ? "-g" : "");
292 append_vcommand_line(asset->path);
294 video_out = new FileMPEGVideo(this);
299 // mjpegtools encoder
301 char string[BCTEXTLEN];
302 sprintf(mjpeg_command, MJPEG_EXE);
304 // Must disable interlacing if MPEG-1
305 switch (asset->vmpeg_preset)
307 case 0: asset->vmpeg_progressive = 1; break;
308 case 1: asset->vmpeg_progressive = 1; break;
309 case 2: asset->vmpeg_progressive = 1; break;
314 // The current usage of mpeg2enc requires bitrate of 0 when quantization is fixed and
315 // quantization of 1 when bitrate is fixed. Perfectly intuitive.
316 if(asset->vmpeg_fix_bitrate)
318 sprintf(string, " -b %d -q 1", asset->vmpeg_bitrate / 1000);
322 sprintf(string, " -b 0 -q %d", asset->vmpeg_quantization);
324 strcat(mjpeg_command, string);
332 int aspect_ratio_code = -1;
333 if(asset->aspect_ratio > 0)
335 for(int i = 0; i < sizeof(aspect_ratio_codes) / sizeof(double); i++)
337 if(EQUIV(aspect_ratio_codes[i], asset->aspect_ratio))
339 aspect_ratio_code = i;
344 if(aspect_ratio_code < 0)
346 eprintf("Unsupported aspect ratio %f\n", asset->aspect_ratio);
347 aspect_ratio_code = 2;
349 sprintf(string, " -a %d", aspect_ratio_code);
350 strcat(mjpeg_command, string);
358 int frame_rate_code = -1;
359 for(int i = 1; sizeof(frame_rate_codes) / sizeof(double); ++i)
361 if(EQUIV(asset->frame_rate, frame_rate_codes[i]))
367 if(frame_rate_code < 0)
370 eprintf("Unsupported frame rate %f\n", asset->frame_rate);
372 sprintf(string, " -F %d", frame_rate_code);
373 strcat(mjpeg_command, string);
379 strcat(mjpeg_command,
380 asset->vmpeg_progressive ? " -I 0" : " -I 1");
384 sprintf(string, " -M %d", file->cpus);
385 strcat(mjpeg_command, string);
388 if(!asset->vmpeg_progressive)
390 strcat(mjpeg_command, asset->vmpeg_field_order ? " -z b" : " -z t");
394 sprintf(string, " -f %d", asset->vmpeg_preset);
395 strcat(mjpeg_command, string);
398 sprintf(string, " -g %d -G %d", asset->vmpeg_iframe_distance, asset->vmpeg_iframe_distance);
399 strcat(mjpeg_command, string);
402 if(asset->vmpeg_seq_codes) strcat(mjpeg_command, " -s");
405 sprintf(string, " -R %d", CLAMP(asset->vmpeg_pframe_distance, 0, 2));
406 strcat(mjpeg_command, string);
408 sprintf(string, " -o '%s'", asset->path);
409 strcat(mjpeg_command, string);
413 eprintf("Running %s\n", mjpeg_command);
414 if(!(mjpeg_out = popen(mjpeg_command, "w")))
416 eprintf("Error while opening \"%s\" for writing. \n%m\n", mjpeg_command);
419 video_out = new FileMPEGVideo(this);
424 if(wr && asset->format == FILE_AMPEG)
426 char command_line[BCTEXTLEN];
427 char encoder_string[BCTEXTLEN];
428 char argument_string[BCTEXTLEN];
430 //printf("FileMPEG::open_file 1 %d\n", asset->ampeg_derivative);
431 encoder_string[0] = 0;
433 if(asset->ampeg_derivative == 2)
435 char string[BCTEXTLEN];
436 append_acommand_line("toolame");
437 append_acommand_line("-m");
438 append_acommand_line((asset->channels >= 2) ? "j" : "m");
439 sprintf(string, "%f", (float)asset->sample_rate / 1000);
440 append_acommand_line("-s");
441 append_acommand_line(string);
442 sprintf(string, "%d", asset->ampeg_bitrate);
443 append_acommand_line("-b");
444 append_acommand_line(string);
445 append_acommand_line("-");
446 append_acommand_line(asset->path);
448 audio_out = new FileMPEGAudio(this);
452 if(asset->ampeg_derivative == 3)
454 lame_global = lame_init();
455 lame_set_brate(lame_global, asset->ampeg_bitrate / 1000);
456 lame_set_quality(lame_global, 0);
457 lame_set_in_samplerate(lame_global,
459 lame_set_num_channels(lame_global,
461 if((result = lame_init_params(lame_global)) < 0)
463 eprintf(_("encode: lame_init_params returned %d\n"), result);
464 lame_close(lame_global);
468 if(!(lame_fd = fopen(asset->path, "w")))
470 eprintf("Error while opening \"%s\" for writing. \n%m\n", asset->path);
471 lame_close(lame_global);
478 eprintf("ampeg_derivative=%d\n", asset->ampeg_derivative);
483 // Transport stream for DVB capture
486 if(!(dvb_out = fopen(asset->path, "w")))
488 eprintf("Error while opening \"%s\" for writing. \n%m\n", asset->path);
507 int FileMPEG::create_index()
509 // Calculate TOC path
510 char index_filename[BCTEXTLEN];
511 char source_filename[BCTEXTLEN];
512 IndexFile::get_index_filename(source_filename,
513 file->preferences->index_directory,
516 char *ptr = strrchr(index_filename, '.');
521 // File is a table of contents.
522 if(fd && mpeg3_has_toc(fd)) return 0;
524 sprintf(ptr, ".toc");
528 // Test existing copy of TOC
529 if((fd = mpeg3_open(index_filename, &error)))
534 // Create progress window.
535 // This gets around the fact that MWindowGUI is locked.
536 char progress_title[BCTEXTLEN];
537 char string[BCTEXTLEN];
538 sprintf(progress_title, "Creating %s\n", index_filename);
540 mpeg3_t *index_file = mpeg3_start_toc(asset->path, index_filename, &total_bytes);
541 struct timeval new_time;
542 struct timeval prev_time;
543 struct timeval start_time;
544 struct timeval current_time;
545 gettimeofday(&prev_time, 0);
546 gettimeofday(&start_time, 0);
548 BC_ProgressBox *progress = new BC_ProgressBox(-1,
556 int64_t bytes_processed;
557 mpeg3_do_toc(index_file, &bytes_processed);
558 gettimeofday(&new_time, 0);
560 if(new_time.tv_sec - prev_time.tv_sec >= 1)
562 gettimeofday(¤t_time, 0);
563 int64_t elapsed_seconds = current_time.tv_sec - start_time.tv_sec;
564 int64_t total_seconds = elapsed_seconds * total_bytes / bytes_processed;
565 int64_t eta = total_seconds - elapsed_seconds;
566 progress->update(bytes_processed, 1);
572 progress->update_title(string, 1);
573 // fprintf(stderr, "ETA: %dm%ds \r",
574 // bytes_processed * 100 / total_bytes,
578 prev_time = new_time;
580 if(bytes_processed >= total_bytes) break;
581 if(progress->is_cancelled())
588 mpeg3_stop_toc(index_file);
590 progress->stop_progress();
596 remove(index_filename);
600 // Fix date to date of source if success
604 if(fd) mpeg3_close(fd);
610 // Reopen file from index path instead of asset path.
613 if(!(fd = mpeg3_open(index_filename, &error)))
629 void FileMPEG::append_vcommand_line(const char *string)
633 char *argv = strdup(string);
634 vcommand_line.append(argv);
638 void FileMPEG::append_acommand_line(const char *string)
642 char *argv = strdup(string);
643 acommand_line.append(argv);
648 int FileMPEG::close_file()
651 next_frame_lock->unlock();
660 // End of sequence signal
661 if(file->asset->vmpeg_cmodel == MPEG_YUV422)
663 mpeg2enc_set_input_buffers(1, 0, 0, 0);
669 vcommand_line.remove_all_objects();
670 acommand_line.remove_all_objects();
674 toolame_send_buffer(0, 0);
680 lame_close(lame_global);
682 if(temp_frame) delete temp_frame;
683 if(toolame_temp) delete [] toolame_temp;
685 if(lame_temp[0]) delete [] lame_temp[0];
686 if(lame_temp[1]) delete [] lame_temp[1];
687 if(lame_output) delete [] lame_output;
688 if(lame_fd) fclose(lame_fd);
690 if(mjpeg_out) fclose(mjpeg_out);
698 FileBase::close_file();
702 int FileMPEG::get_best_colormodel(Asset *asset, int driver)
704 //printf("FileMPEG::get_best_colormodel 1\n");
709 if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
710 if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
712 case PLAYBACK_X11_XV:
713 case PLAYBACK_ASYNCHRONOUS:
714 if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
715 if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
717 case PLAYBACK_X11_GL:
724 case PLAYBACK_DV1394:
725 case PLAYBACK_FIREWIRE:
730 if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
731 if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
737 case CAPTURE_FIREWIRE:
738 case CAPTURE_IEC61883:
742 //printf("FileMPEG::get_best_colormodel 100\n");
745 int FileMPEG::colormodel_supported(int colormodel)
750 int FileMPEG::get_index(char *index_path)
755 // Convert the index tables from tracks to channels.
756 if(mpeg3_index_tracks(fd))
758 // Calculate size of buffer needed for all channels
760 for(int i = 0; i < mpeg3_index_tracks(fd); i++)
762 buffer_size += mpeg3_index_size(fd, i) *
763 mpeg3_index_channels(fd, i) *
767 asset->index_buffer = new float[buffer_size];
769 // Size of index buffer in floats
770 int current_offset = 0;
771 // Current asset channel
772 int current_channel = 0;
773 asset->index_zoom = mpeg3_index_zoom(fd);
774 asset->index_offsets = new int64_t[asset->channels];
775 asset->index_sizes = new int64_t[asset->channels];
776 for(int i = 0; i < mpeg3_index_tracks(fd); i++)
778 for(int j = 0; j < mpeg3_index_channels(fd, i); j++)
780 asset->index_offsets[current_channel] = current_offset;
781 asset->index_sizes[current_channel] = mpeg3_index_size(fd, i) * 2;
782 memcpy(asset->index_buffer + current_offset,
783 mpeg3_index_data(fd, i, j),
784 mpeg3_index_size(fd, i) * sizeof(float) * 2);
786 current_offset += mpeg3_index_size(fd, i) * 2;
792 asset->index_bytes = fs.get_size(asset->path);
794 asset->write_index(index_path, buffer_size * sizeof(float));
795 delete [] asset->index_buffer;
804 int FileMPEG::can_copy_from(Edit *edit, int64_t position)
810 int FileMPEG::set_audio_position(int64_t sample)
816 to_streamchannel(file->current_channel, stream, channel);
818 //printf("FileMPEG::set_audio_position %d %d %d\n", sample, mpeg3_get_sample(fd, stream), last_sample);
819 if(sample != mpeg3_get_sample(fd, stream) &&
820 sample != last_sample)
822 if(sample >= 0 && sample < asset->audio_length)
824 //printf("FileMPEG::set_audio_position seeking stream %d\n", sample);
825 return mpeg3_set_sample(fd, sample, stream);
834 int FileMPEG::set_video_position(int64_t x)
837 if(x >= 0 && x < asset->video_length)
839 //printf("FileMPEG::set_video_position 1 %lld\n", x);
840 mpeg3_set_frame(fd, x, file->current_layer);
846 int64_t FileMPEG::get_memory_usage()
850 int64_t result = mpeg3_memory_usage(fd);
857 int FileMPEG::write_samples(double **buffer, int64_t len)
861 //printf("FileMPEG::write_samples 1\n");
862 if(asset->ampeg_derivative == 2)
865 int channels = MIN(asset->channels, 2);
866 int64_t audio_size = len * channels * 2;
867 if(toolame_allocation < audio_size)
869 if(toolame_temp) delete [] toolame_temp;
870 toolame_temp = new unsigned char[audio_size];
871 toolame_allocation = audio_size;
874 for(int i = 0; i < channels; i++)
876 int16_t *output = ((int16_t*)toolame_temp) + i;
877 double *input = buffer[i];
878 for(int j = 0; j < len; j++)
880 int sample = (int)(*input * 0x7fff);
881 *output = (int16_t)(CLIP(sample, -0x8000, 0x7fff));
886 result = toolame_send_buffer((char*)toolame_temp, audio_size);
889 if(asset->ampeg_derivative == 3)
891 int channels = MIN(asset->channels, 2);
892 int64_t audio_size = len * channels;
893 if(!lame_global) return 1;
894 if(!lame_fd) return 1;
895 if(lame_allocation < audio_size)
897 if(lame_temp[0]) delete [] lame_temp[0];
898 if(lame_temp[1]) delete [] lame_temp[1];
899 lame_temp[0] = new float[audio_size];
900 lame_temp[1] = new float[audio_size];
901 lame_allocation = audio_size;
904 if(lame_output_allocation < audio_size * 4)
906 if(lame_output) delete [] lame_output;
907 lame_output_allocation = audio_size * 4;
908 lame_output = new char[lame_output_allocation];
911 for(int i = 0; i < channels; i++)
913 float *output = lame_temp[i];
914 double *input = buffer[i];
915 for(int j = 0; j < len; j++)
917 *output++ = *input++ * (float)32768;
921 result = lame_encode_buffer_float(lame_global,
923 (channels > 1) ? lame_temp[1] : lame_temp[0],
925 (unsigned char*)lame_output,
926 lame_output_allocation);
929 char *real_output = lame_output;
933 for(int i = 0; i < bytes; i++)
936 real_output = &lame_output[i];
942 if(bytes > 0 && lame_started)
944 result = !fwrite(real_output, 1, bytes, lame_fd);
946 eprintf("Error while writing samples");
958 int FileMPEG::write_frames(VFrame ***frames, int len)
964 int temp_w = (int)((asset->width + 15) / 16) * 16;
969 (asset->vmpeg_cmodel == MPEG_YUV420) ? BC_YUV420P : BC_YUV422P;
972 // Height depends on progressiveness
973 if(asset->vmpeg_progressive || asset->vmpeg_derivative == 1)
974 temp_h = (int)((asset->height + 15) / 16) * 16;
976 temp_h = (int)((asset->height + 31) / 32) * 32;
978 //printf("FileMPEG::write_frames 1\n");
980 // Only 1 layer is supported in MPEG output
981 for(int i = 0; i < 1; i++)
983 for(int j = 0; j < len && !result; j++)
985 VFrame *frame = frames[i][j];
989 if(asset->vmpeg_cmodel == MPEG_YUV422)
991 if(frame->get_w() == temp_w &&
992 frame->get_h() == temp_h &&
993 frame->get_color_model() == output_cmodel)
995 mpeg2enc_set_input_buffers(0,
996 (char*)frame->get_y(),
997 (char*)frame->get_u(),
998 (char*)frame->get_v());
1003 (temp_frame->get_w() != temp_w ||
1004 temp_frame->get_h() != temp_h ||
1005 temp_frame->get_color_model() || output_cmodel))
1014 temp_frame = new VFrame(0,
1020 cmodel_transfer(temp_frame->get_rows(),
1022 temp_frame->get_y(),
1023 temp_frame->get_u(),
1024 temp_frame->get_v(),
1036 frame->get_color_model(),
1037 temp_frame->get_color_model(),
1042 mpeg2enc_set_input_buffers(0,
1043 (char*)temp_frame->get_y(),
1044 (char*)temp_frame->get_u(),
1045 (char*)temp_frame->get_v());
1050 // MJPEG uses the same dimensions as the input
1051 if(frame->get_color_model() == output_cmodel)
1053 mjpeg_y = frame->get_y();
1054 mjpeg_u = frame->get_u();
1055 mjpeg_v = frame->get_v();
1061 temp_frame = new VFrame(0,
1067 cmodel_transfer(temp_frame->get_rows(),
1069 temp_frame->get_y(),
1070 temp_frame->get_u(),
1071 temp_frame->get_v(),
1083 frame->get_color_model(),
1084 temp_frame->get_color_model(),
1089 mjpeg_y = temp_frame->get_y();
1090 mjpeg_u = temp_frame->get_u();
1091 mjpeg_v = temp_frame->get_v();
1097 next_frame_lock->unlock();
1098 next_frame_done->lock("FileMPEG::write_frames");
1099 if(mjpeg_error) result = 1;
1115 int FileMPEG::read_frame(VFrame *frame)
1121 // printf("FileMPEG::read_frame\n");
1122 // frame->dump_stacks();
1123 // frame->dump_params();
1125 if(mpeg3_colormodel(fd, 0) == MPEG3_YUV420P)
1126 src_cmodel = BC_YUV420P;
1128 if(mpeg3_colormodel(fd, 0) == MPEG3_YUV422P)
1129 src_cmodel = BC_YUV422P;
1131 switch(frame->get_color_model())
1135 case MPEG3_BGRA8888:
1137 case MPEG3_RGBA8888:
1138 case MPEG3_RGBA16161616:
1140 mpeg3_read_frame(fd,
1141 frame->get_rows(), /* Array of pointers to the start of each output row */
1142 0, /* Location in input frame to take picture */
1146 asset->width, /* Dimensions of output_rows */
1148 frame->get_color_model(), /* One of the color model #defines */
1149 file->current_layer);
1155 // Read these directly
1156 if(frame->get_color_model() == src_cmodel)
1159 mpeg3_read_yuvframe(fd,
1160 (char*)frame->get_y(),
1161 (char*)frame->get_u(),
1162 (char*)frame->get_v(),
1167 file->current_layer);
1171 // Process through temp frame
1175 mpeg3_read_yuvframe_ptr(fd,
1179 file->current_layer);
1183 cmodel_transfer(frame->get_rows(),
1200 frame->get_color_model(),
1214 void FileMPEG::to_streamchannel(int channel, int &stream_out, int &channel_out)
1216 for(stream_out = 0, channel_out = file->current_channel;
1217 stream_out < mpeg3_total_astreams(fd) &&
1218 channel_out >= mpeg3_audio_channels(fd, stream_out);
1219 channel_out -= mpeg3_audio_channels(fd, stream_out), stream_out++)
1223 int FileMPEG::read_samples(double *buffer, int64_t len)
1226 if(len < 0) return 0;
1228 // This is directed to a FileMPEGBuffer
1229 float *temp_float = new float[len];
1230 // Translate pure channel to a stream and a channel in the mpeg stream
1231 int stream, channel;
1232 to_streamchannel(file->current_channel, stream, channel);
1236 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
1238 mpeg3_set_sample(fd,
1239 file->current_sample,
1241 mpeg3_read_audio(fd,
1242 temp_float, /* Pointer to pre-allocated buffer of floats */
1243 0, /* Pointer to pre-allocated buffer of int16's */
1244 channel, /* Channel to decode */
1245 len, /* Number of samples to decode */
1246 stream); /* Stream containing the channel */
1249 // last_sample = file->current_sample;
1250 for(int i = 0; i < len; i++) buffer[i] = temp_float[i];
1252 delete [] temp_float;
1256 int FileMPEG::prefer_samples_float()
1261 int FileMPEG::read_samples_float(float *buffer, int64_t len)
1265 // Translate pure channel to a stream and a channel in the mpeg stream
1266 int stream, channel;
1267 to_streamchannel(file->current_channel, stream, channel);
1270 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
1272 mpeg3_set_sample(fd,
1273 file->current_sample,
1275 mpeg3_read_audio(fd,
1276 buffer, /* Pointer to pre-allocated buffer of floats */
1277 0, /* Pointer to pre-allocated buffer of int16's */
1278 channel, /* Channel to decode */
1279 len, /* Number of samples to decode */
1280 stream); /* Stream containing the channel */
1283 // last_sample = file->current_sample;
1285 //printf("FileMPEG::read_samples 100\n");
1291 char* FileMPEG::strtocompression(char *string)
1296 char* FileMPEG::compressiontostr(char *string)
1307 FileMPEGVideo::FileMPEGVideo(FileMPEG *file)
1313 if(file->asset->vmpeg_cmodel == MPEG_YUV422)
1315 mpeg2enc_init_buffers();
1316 mpeg2enc_set_w(file->asset->width);
1317 mpeg2enc_set_h(file->asset->height);
1318 mpeg2enc_set_rate(file->asset->frame_rate);
1322 FileMPEGVideo::~FileMPEGVideo()
1327 void FileMPEGVideo::run()
1329 if(file->asset->vmpeg_cmodel == MPEG_YUV422)
1331 printf("FileMPEGVideo::run ");
1332 for(int i = 0; i < file->vcommand_line.total; i++)
1333 printf("%s ", file->vcommand_line.values[i]);
1335 mpeg2enc(file->vcommand_line.total, file->vcommand_line.values);
1341 file->next_frame_lock->lock("FileMPEGVideo::run");
1344 file->next_frame_done->unlock();
1350 // YUV4 sequence header
1351 if(!file->wrote_header)
1353 file->wrote_header = 1;
1355 char string[BCTEXTLEN];
1356 char interlace_string[BCTEXTLEN];
1357 if(!file->asset->vmpeg_progressive)
1359 sprintf(interlace_string, file->asset->vmpeg_field_order ? "b" : "t");
1363 sprintf(interlace_string, "p");
1366 fprintf(file->mjpeg_out, "YUV4MPEG2 W%d H%d F%d:%d I%s A%d:%d C%s\n",
1368 file->asset->height,
1369 (int)(file->asset->frame_rate * 1001),
1372 (int)(file->asset->aspect_ratio * 1000),
1377 // YUV4 frame header
1378 fprintf(file->mjpeg_out, "FRAME\n");
1381 if(!fwrite(file->mjpeg_y, file->asset->width * file->asset->height, 1, file->mjpeg_out))
1382 file->mjpeg_error = 1;
1383 if(!fwrite(file->mjpeg_u, file->asset->width * file->asset->height / 4, 1, file->mjpeg_out))
1384 file->mjpeg_error = 1;
1385 if(!fwrite(file->mjpeg_v, file->asset->width * file->asset->height / 4, 1, file->mjpeg_out))
1386 file->mjpeg_error = 1;
1387 fflush(file->mjpeg_out);
1389 file->next_frame_done->unlock();
1391 pclose(file->mjpeg_out);
1392 file->mjpeg_out = 0;
1415 FileMPEGAudio::FileMPEGAudio(FileMPEG *file)
1419 toolame_init_buffers();
1422 FileMPEGAudio::~FileMPEGAudio()
1427 void FileMPEGAudio::run()
1429 file->toolame_result = toolame(file->acommand_line.total, file->acommand_line.values);
1439 MPEGConfigAudio::MPEGConfigAudio(BC_WindowBase *parent_window, Asset *asset)
1440 : BC_Window(PROGRAM_NAME ": Audio Compression",
1441 parent_window->get_abs_cursor_x(1),
1442 parent_window->get_abs_cursor_y(1),
1451 this->parent_window = parent_window;
1452 this->asset = asset;
1455 MPEGConfigAudio::~MPEGConfigAudio()
1459 int MPEGConfigAudio::create_objects()
1466 if(asset->format == FILE_MPEG)
1468 add_subwindow(new BC_Title(x, y, _("No options for MPEG transport stream.")));
1473 add_tool(new BC_Title(x, y, _("Layer:")));
1474 add_tool(layer = new MPEGLayer(x1, y, this));
1475 layer->create_objects();
1478 add_tool(new BC_Title(x, y, _("Kbits per second:")));
1479 add_tool(bitrate = new MPEGABitrate(x1, y, this));
1480 bitrate->create_objects();
1483 add_subwindow(new BC_OKButton(this));
1489 int MPEGConfigAudio::close_event()
1501 MPEGLayer::MPEGLayer(int x, int y, MPEGConfigAudio *gui)
1502 : BC_PopupMenu(x, y, 100, layer_to_string(gui->asset->ampeg_derivative))
1507 void MPEGLayer::create_objects()
1509 add_item(new BC_MenuItem(layer_to_string(2)));
1510 add_item(new BC_MenuItem(layer_to_string(3)));
1513 int MPEGLayer::handle_event()
1515 gui->asset->ampeg_derivative = string_to_layer(get_text());
1516 gui->bitrate->set_layer(gui->asset->ampeg_derivative);
1520 int MPEGLayer::string_to_layer(char *string)
1522 if(!strcasecmp(layer_to_string(2), string))
1524 if(!strcasecmp(layer_to_string(3), string))
1530 char* MPEGLayer::layer_to_string(int layer)
1554 MPEGABitrate::MPEGABitrate(int x, int y, MPEGConfigAudio *gui)
1558 bitrate_to_string(gui->string, gui->asset->ampeg_bitrate))
1563 void MPEGABitrate::create_objects()
1565 set_layer(gui->asset->ampeg_derivative);
1568 void MPEGABitrate::set_layer(int layer)
1570 while(total_items())
1577 add_item(new BC_MenuItem("160"));
1578 add_item(new BC_MenuItem("192"));
1579 add_item(new BC_MenuItem("224"));
1580 add_item(new BC_MenuItem("256"));
1581 add_item(new BC_MenuItem("320"));
1582 add_item(new BC_MenuItem("384"));
1586 add_item(new BC_MenuItem("8"));
1587 add_item(new BC_MenuItem("16"));
1588 add_item(new BC_MenuItem("24"));
1589 add_item(new BC_MenuItem("32"));
1590 add_item(new BC_MenuItem("40"));
1591 add_item(new BC_MenuItem("48"));
1592 add_item(new BC_MenuItem("56"));
1593 add_item(new BC_MenuItem("64"));
1594 add_item(new BC_MenuItem("80"));
1595 add_item(new BC_MenuItem("96"));
1596 add_item(new BC_MenuItem("112"));
1597 add_item(new BC_MenuItem("128"));
1598 add_item(new BC_MenuItem("144"));
1599 add_item(new BC_MenuItem("160"));
1600 add_item(new BC_MenuItem("192"));
1601 add_item(new BC_MenuItem("224"));
1602 add_item(new BC_MenuItem("256"));
1603 add_item(new BC_MenuItem("320"));
1607 int MPEGABitrate::handle_event()
1609 gui->asset->ampeg_bitrate = string_to_bitrate(get_text());
1613 int MPEGABitrate::string_to_bitrate(char *string)
1615 return atol(string);
1619 char* MPEGABitrate::bitrate_to_string(char *string, int bitrate)
1621 sprintf(string, "%d", bitrate);
1633 MPEGConfigVideo::MPEGConfigVideo(BC_WindowBase *parent_window,
1635 : BC_Window(PROGRAM_NAME ": Video Compression",
1636 parent_window->get_abs_cursor_x(1),
1637 parent_window->get_abs_cursor_y(1),
1646 this->parent_window = parent_window;
1647 this->asset = asset;
1651 MPEGConfigVideo::~MPEGConfigVideo()
1655 int MPEGConfigVideo::create_objects()
1661 if(asset->format == FILE_MPEG)
1663 add_subwindow(new BC_Title(x, y, _("No options for MPEG transport stream.")));
1667 add_subwindow(new BC_Title(x, y, _("Color model:")));
1668 add_subwindow(cmodel = new MPEGColorModel(x1, y, this));
1669 cmodel->create_objects();
1672 update_cmodel_objs();
1674 add_subwindow(new BC_OKButton(this));
1680 int MPEGConfigVideo::close_event()
1687 void MPEGConfigVideo::delete_cmodel_objs()
1692 delete fixed_bitrate;
1695 delete iframe_distance;
1696 delete pframe_distance;
1697 delete top_field_first;
1701 titles.remove_all_objects();
1705 void MPEGConfigVideo::reset_cmodel()
1713 iframe_distance = 0;
1714 pframe_distance = 0;
1715 top_field_first = 0;
1721 void MPEGConfigVideo::update_cmodel_objs()
1729 delete_cmodel_objs();
1731 if(asset->vmpeg_cmodel == MPEG_YUV420)
1733 add_subwindow(title = new BC_Title(x, y + 5, _("Format Preset:")));
1734 titles.append(title);
1735 add_subwindow(preset = new MPEGPreset(x1, y, this));
1736 preset->create_objects();
1740 add_subwindow(title = new BC_Title(x, y + 5, _("Derivative:")));
1741 titles.append(title);
1742 add_subwindow(derivative = new MPEGDerivative(x1, y, this));
1743 derivative->create_objects();
1746 add_subwindow(title = new BC_Title(x, y + 5, _("Bitrate:")));
1747 titles.append(title);
1748 add_subwindow(bitrate = new MPEGBitrate(x1, y, this));
1749 add_subwindow(fixed_bitrate = new MPEGFixedBitrate(x2, y, this));
1752 add_subwindow(title = new BC_Title(x, y, _("Quantization:")));
1753 titles.append(title);
1754 quant = new MPEGQuant(x1, y, this);
1755 quant->create_objects();
1756 add_subwindow(fixed_quant = new MPEGFixedQuant(x2, y, this));
1759 add_subwindow(title = new BC_Title(x, y, _("I frame distance:")));
1760 titles.append(title);
1761 iframe_distance = new MPEGIFrameDistance(x1, y, this);
1762 iframe_distance->create_objects();
1765 if(asset->vmpeg_cmodel == MPEG_YUV420)
1767 add_subwindow(title = new BC_Title(x, y, _("P frame distance:")));
1768 titles.append(title);
1769 pframe_distance = new MPEGPFrameDistance(x1, y, this);
1770 pframe_distance->create_objects();
1773 add_subwindow(top_field_first = new BC_CheckBox(x, y, &asset->vmpeg_field_order, _("Bottom field first")));
1777 add_subwindow(progressive = new BC_CheckBox(x, y, &asset->vmpeg_progressive, _("Progressive frames")));
1779 add_subwindow(denoise = new BC_CheckBox(x, y, &asset->vmpeg_denoise, _("Denoise")));
1781 add_subwindow(seq_codes = new BC_CheckBox(x, y, &asset->vmpeg_seq_codes, _("Sequence start codes in every GOP")));
1797 MPEGDerivative::MPEGDerivative(int x, int y, MPEGConfigVideo *gui)
1798 : BC_PopupMenu(x, y, 150, derivative_to_string(gui->asset->vmpeg_derivative))
1803 void MPEGDerivative::create_objects()
1805 add_item(new BC_MenuItem(derivative_to_string(1)));
1806 add_item(new BC_MenuItem(derivative_to_string(2)));
1809 int MPEGDerivative::handle_event()
1811 gui->asset->vmpeg_derivative = string_to_derivative(get_text());
1815 int MPEGDerivative::string_to_derivative(char *string)
1817 if(!strcasecmp(derivative_to_string(1), string))
1819 if(!strcasecmp(derivative_to_string(2), string))
1825 char* MPEGDerivative::derivative_to_string(int derivative)
1853 MPEGPreset::MPEGPreset(int x, int y, MPEGConfigVideo *gui)
1854 : BC_PopupMenu(x, y, 200, value_to_string(gui->asset->vmpeg_preset))
1859 void MPEGPreset::create_objects()
1861 for(int i = 0; i < 10; i++)
1863 add_item(new BC_MenuItem(value_to_string(i)));
1867 int MPEGPreset::handle_event()
1869 gui->asset->vmpeg_preset = string_to_value(get_text());
1873 int MPEGPreset::string_to_value(char *string)
1875 for(int i = 0; i < 10; i++)
1877 if(!strcasecmp(value_to_string(i), string))
1883 char* MPEGPreset::value_to_string(int derivative)
1887 case 0: return _("Generic MPEG-1"); break;
1888 case 1: return _("standard VCD"); break;
1889 case 2: return _("user VCD"); break;
1890 case 3: return _("Generic MPEG-2"); break;
1891 case 4: return _("standard SVCD"); break;
1892 case 5: return _("user SVCD"); break;
1893 case 6: return _("VCD Still sequence"); break;
1894 case 7: return _("SVCD Still sequence"); break;
1895 case 8: return _("DVD NAV"); break;
1896 case 9: return _("DVD"); break;
1897 default: return _("Generic MPEG-1"); break;
1911 MPEGBitrate::MPEGBitrate(int x, int y, MPEGConfigVideo *gui)
1912 : BC_TextBox(x, y, 100, 1, gui->asset->vmpeg_bitrate)
1918 int MPEGBitrate::handle_event()
1920 gui->asset->vmpeg_bitrate = atol(get_text());
1928 MPEGQuant::MPEGQuant(int x, int y, MPEGConfigVideo *gui)
1929 : BC_TumbleTextBox(gui,
1930 (int64_t)gui->asset->vmpeg_quantization,
1940 int MPEGQuant::handle_event()
1942 gui->asset->vmpeg_quantization = atol(get_text());
1946 MPEGFixedBitrate::MPEGFixedBitrate(int x, int y, MPEGConfigVideo *gui)
1947 : BC_Radial(x, y, gui->asset->vmpeg_fix_bitrate, _("Fixed bitrate"))
1952 int MPEGFixedBitrate::handle_event()
1955 gui->asset->vmpeg_fix_bitrate = 1;
1956 gui->fixed_quant->update(0);
1960 MPEGFixedQuant::MPEGFixedQuant(int x, int y, MPEGConfigVideo *gui)
1961 : BC_Radial(x, y, !gui->asset->vmpeg_fix_bitrate, _("Fixed quantization"))
1966 int MPEGFixedQuant::handle_event()
1969 gui->asset->vmpeg_fix_bitrate = 0;
1970 gui->fixed_bitrate->update(0);
1982 MPEGIFrameDistance::MPEGIFrameDistance(int x, int y, MPEGConfigVideo *gui)
1983 : BC_TumbleTextBox(gui,
1984 (int64_t)gui->asset->vmpeg_iframe_distance,
1994 int MPEGIFrameDistance::handle_event()
1996 gui->asset->vmpeg_iframe_distance = atoi(get_text());
2006 MPEGPFrameDistance::MPEGPFrameDistance(int x, int y, MPEGConfigVideo *gui)
2007 : BC_TumbleTextBox(gui,
2008 (int64_t)gui->asset->vmpeg_pframe_distance,
2018 int MPEGPFrameDistance::handle_event()
2020 gui->asset->vmpeg_pframe_distance = atoi(get_text());
2031 MPEGColorModel::MPEGColorModel(int x, int y, MPEGConfigVideo *gui)
2032 : BC_PopupMenu(x, y, 150, cmodel_to_string(gui->asset->vmpeg_cmodel))
2037 void MPEGColorModel::create_objects()
2039 add_item(new BC_MenuItem(cmodel_to_string(0)));
2040 add_item(new BC_MenuItem(cmodel_to_string(1)));
2043 int MPEGColorModel::handle_event()
2045 gui->asset->vmpeg_cmodel = string_to_cmodel(get_text());
2046 gui->update_cmodel_objs();
2050 int MPEGColorModel::string_to_cmodel(char *string)
2052 if(!strcasecmp(cmodel_to_string(0), string))
2054 if(!strcasecmp(cmodel_to_string(1), string))
2059 char* MPEGColorModel::cmodel_to_string(int cmodel)
2064 return _("YUV 4:2:0");
2068 return _("YUV 4:2:2");
2072 return _("YUV 4:2:0");