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);
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");
529 // Test existing copy of TOC
530 mpeg3_close(fd); // Always free old fd
531 if((fd_toc = mpeg3_open(index_filename, &error)))
533 // Just exchange old fd
537 // Create progress window.
538 // This gets around the fact that MWindowGUI is locked.
539 char progress_title[BCTEXTLEN];
540 char string[BCTEXTLEN];
541 sprintf(progress_title, "Creating %s\n", index_filename);
543 mpeg3_t *index_file = mpeg3_start_toc(asset->path, index_filename, &total_bytes);
544 struct timeval new_time;
545 struct timeval prev_time;
546 struct timeval start_time;
547 struct timeval current_time;
548 gettimeofday(&prev_time, 0);
549 gettimeofday(&start_time, 0);
551 BC_ProgressBox *progress = new BC_ProgressBox(-1,
559 int64_t bytes_processed;
560 mpeg3_do_toc(index_file, &bytes_processed);
561 gettimeofday(&new_time, 0);
563 if(new_time.tv_sec - prev_time.tv_sec >= 1)
565 gettimeofday(¤t_time, 0);
566 int64_t elapsed_seconds = current_time.tv_sec - start_time.tv_sec;
567 int64_t total_seconds = elapsed_seconds * total_bytes / bytes_processed;
568 int64_t eta = total_seconds - elapsed_seconds;
569 progress->update(bytes_processed, 1);
575 progress->update_title(string, 1);
576 // fprintf(stderr, "ETA: %dm%ds \r",
577 // bytes_processed * 100 / total_bytes,
581 prev_time = new_time;
583 if(bytes_processed >= total_bytes) break;
584 if(progress->is_cancelled())
591 mpeg3_stop_toc(index_file);
593 progress->stop_progress();
599 remove(index_filename);
603 // Reopen file from index path instead of asset path.
604 if(!(fd = mpeg3_open(index_filename, &error)))
616 void FileMPEG::append_vcommand_line(const char *string)
620 char *argv = strdup(string);
621 vcommand_line.append(argv);
625 void FileMPEG::append_acommand_line(const char *string)
629 char *argv = strdup(string);
630 acommand_line.append(argv);
635 int FileMPEG::close_file()
638 next_frame_lock->unlock();
647 // End of sequence signal
648 if(file->asset->vmpeg_cmodel == MPEG_YUV422)
650 mpeg2enc_set_input_buffers(1, 0, 0, 0);
656 vcommand_line.remove_all_objects();
657 acommand_line.remove_all_objects();
661 toolame_send_buffer(0, 0);
667 lame_close(lame_global);
669 if(temp_frame) delete temp_frame;
670 if(toolame_temp) delete [] toolame_temp;
672 if(lame_temp[0]) delete [] lame_temp[0];
673 if(lame_temp[1]) delete [] lame_temp[1];
674 if(lame_output) delete [] lame_output;
675 if(lame_fd) fclose(lame_fd);
677 if(mjpeg_out) fclose(mjpeg_out);
685 FileBase::close_file();
689 int FileMPEG::get_best_colormodel(Asset *asset, int driver)
691 //printf("FileMPEG::get_best_colormodel 1\n");
696 if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
697 if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
699 case PLAYBACK_X11_XV:
700 case PLAYBACK_ASYNCHRONOUS:
701 if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
702 if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
704 case PLAYBACK_X11_GL:
711 case PLAYBACK_DV1394:
712 case PLAYBACK_FIREWIRE:
717 if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
718 if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
724 case CAPTURE_FIREWIRE:
725 case CAPTURE_IEC61883:
729 //printf("FileMPEG::get_best_colormodel 100\n");
732 int FileMPEG::colormodel_supported(int colormodel)
737 int FileMPEG::get_index(char *index_path)
742 // Convert the index tables from tracks to channels.
743 if(mpeg3_index_tracks(fd))
745 // Calculate size of buffer needed for all channels
747 for(int i = 0; i < mpeg3_index_tracks(fd); i++)
749 buffer_size += mpeg3_index_size(fd, i) *
750 mpeg3_index_channels(fd, i) *
754 asset->index_buffer = new float[buffer_size];
756 // Size of index buffer in floats
757 int current_offset = 0;
758 // Current asset channel
759 int current_channel = 0;
760 asset->index_zoom = mpeg3_index_zoom(fd);
761 asset->index_offsets = new int64_t[asset->channels];
762 asset->index_sizes = new int64_t[asset->channels];
763 for(int i = 0; i < mpeg3_index_tracks(fd); i++)
765 for(int j = 0; j < mpeg3_index_channels(fd, i); j++)
767 asset->index_offsets[current_channel] = current_offset;
768 asset->index_sizes[current_channel] = mpeg3_index_size(fd, i) * 2;
769 memcpy(asset->index_buffer + current_offset,
770 mpeg3_index_data(fd, i, j),
771 mpeg3_index_size(fd, i) * sizeof(float) * 2);
773 current_offset += mpeg3_index_size(fd, i) * 2;
779 asset->index_bytes = fs.get_size(asset->path);
781 asset->write_index(index_path, buffer_size * sizeof(float));
782 delete [] asset->index_buffer;
791 int FileMPEG::can_copy_from(Edit *edit, int64_t position)
797 int FileMPEG::set_audio_position(int64_t sample)
803 to_streamchannel(file->current_channel, stream, channel);
805 //printf("FileMPEG::set_audio_position %d %d %d\n", sample, mpeg3_get_sample(fd, stream), last_sample);
806 if(sample != mpeg3_get_sample(fd, stream) &&
807 sample != last_sample)
809 if(sample >= 0 && sample < asset->audio_length)
811 //printf("FileMPEG::set_audio_position seeking stream %d\n", sample);
812 return mpeg3_set_sample(fd, sample, stream);
821 int FileMPEG::set_video_position(int64_t x)
824 if(x >= 0 && x < asset->video_length)
826 //printf("FileMPEG::set_video_position 1 %lld\n", x);
827 mpeg3_set_frame(fd, x, file->current_layer);
833 int64_t FileMPEG::get_memory_usage()
837 int64_t result = mpeg3_memory_usage(fd);
844 int FileMPEG::write_samples(double **buffer, int64_t len)
848 //printf("FileMPEG::write_samples 1\n");
849 if(asset->ampeg_derivative == 2)
852 int channels = MIN(asset->channels, 2);
853 int64_t audio_size = len * channels * 2;
854 if(toolame_allocation < audio_size)
856 if(toolame_temp) delete [] toolame_temp;
857 toolame_temp = new unsigned char[audio_size];
858 toolame_allocation = audio_size;
861 for(int i = 0; i < channels; i++)
863 int16_t *output = ((int16_t*)toolame_temp) + i;
864 double *input = buffer[i];
865 for(int j = 0; j < len; j++)
867 int sample = (int)(*input * 0x7fff);
868 *output = (int16_t)(CLIP(sample, -0x8000, 0x7fff));
873 result = toolame_send_buffer((char*)toolame_temp, audio_size);
876 if(asset->ampeg_derivative == 3)
878 int channels = MIN(asset->channels, 2);
879 int64_t audio_size = len * channels;
880 if(!lame_global) return 1;
881 if(!lame_fd) return 1;
882 if(lame_allocation < audio_size)
884 if(lame_temp[0]) delete [] lame_temp[0];
885 if(lame_temp[1]) delete [] lame_temp[1];
886 lame_temp[0] = new float[audio_size];
887 lame_temp[1] = new float[audio_size];
888 lame_allocation = audio_size;
891 if(lame_output_allocation < audio_size * 4)
893 if(lame_output) delete [] lame_output;
894 lame_output_allocation = audio_size * 4;
895 lame_output = new char[lame_output_allocation];
898 for(int i = 0; i < channels; i++)
900 float *output = lame_temp[i];
901 double *input = buffer[i];
902 for(int j = 0; j < len; j++)
904 *output++ = *input++ * (float)32768;
908 result = lame_encode_buffer_float(lame_global,
910 (channels > 1) ? lame_temp[1] : lame_temp[0],
912 (unsigned char*)lame_output,
913 lame_output_allocation);
916 char *real_output = lame_output;
920 for(int i = 0; i < bytes; i++)
923 real_output = &lame_output[i];
929 if(bytes > 0 && lame_started)
931 result = !fwrite(real_output, 1, bytes, lame_fd);
933 eprintf("Error while writing samples");
945 int FileMPEG::write_frames(VFrame ***frames, int len)
951 int temp_w = (int)((asset->width + 15) / 16) * 16;
956 (asset->vmpeg_cmodel == MPEG_YUV420) ? BC_YUV420P : BC_YUV422P;
959 // Height depends on progressiveness
960 if(asset->vmpeg_progressive || asset->vmpeg_derivative == 1)
961 temp_h = (int)((asset->height + 15) / 16) * 16;
963 temp_h = (int)((asset->height + 31) / 32) * 32;
965 //printf("FileMPEG::write_frames 1\n");
967 // Only 1 layer is supported in MPEG output
968 for(int i = 0; i < 1; i++)
970 for(int j = 0; j < len && !result; j++)
972 VFrame *frame = frames[i][j];
976 if(asset->vmpeg_cmodel == MPEG_YUV422)
978 if(frame->get_w() == temp_w &&
979 frame->get_h() == temp_h &&
980 frame->get_color_model() == output_cmodel)
982 mpeg2enc_set_input_buffers(0,
983 (char*)frame->get_y(),
984 (char*)frame->get_u(),
985 (char*)frame->get_v());
990 (temp_frame->get_w() != temp_w ||
991 temp_frame->get_h() != temp_h ||
992 temp_frame->get_color_model() || output_cmodel))
1001 temp_frame = new VFrame(0,
1007 cmodel_transfer(temp_frame->get_rows(),
1009 temp_frame->get_y(),
1010 temp_frame->get_u(),
1011 temp_frame->get_v(),
1023 frame->get_color_model(),
1024 temp_frame->get_color_model(),
1029 mpeg2enc_set_input_buffers(0,
1030 (char*)temp_frame->get_y(),
1031 (char*)temp_frame->get_u(),
1032 (char*)temp_frame->get_v());
1037 // MJPEG uses the same dimensions as the input
1038 if(frame->get_color_model() == output_cmodel)
1040 mjpeg_y = frame->get_y();
1041 mjpeg_u = frame->get_u();
1042 mjpeg_v = frame->get_v();
1048 temp_frame = new VFrame(0,
1054 cmodel_transfer(temp_frame->get_rows(),
1056 temp_frame->get_y(),
1057 temp_frame->get_u(),
1058 temp_frame->get_v(),
1070 frame->get_color_model(),
1071 temp_frame->get_color_model(),
1076 mjpeg_y = temp_frame->get_y();
1077 mjpeg_u = temp_frame->get_u();
1078 mjpeg_v = temp_frame->get_v();
1084 next_frame_lock->unlock();
1085 next_frame_done->lock("FileMPEG::write_frames");
1086 if(mjpeg_error) result = 1;
1102 int FileMPEG::read_frame(VFrame *frame)
1108 // printf("FileMPEG::read_frame\n");
1109 // frame->dump_stacks();
1110 // frame->dump_params();
1112 if(mpeg3_colormodel(fd, 0) == MPEG3_YUV420P)
1113 src_cmodel = BC_YUV420P;
1115 if(mpeg3_colormodel(fd, 0) == MPEG3_YUV422P)
1116 src_cmodel = BC_YUV422P;
1118 switch(frame->get_color_model())
1122 case MPEG3_BGRA8888:
1124 case MPEG3_RGBA8888:
1125 case MPEG3_RGBA16161616:
1127 mpeg3_read_frame(fd,
1128 frame->get_rows(), /* Array of pointers to the start of each output row */
1129 0, /* Location in input frame to take picture */
1133 asset->width, /* Dimensions of output_rows */
1135 frame->get_color_model(), /* One of the color model #defines */
1136 file->current_layer);
1142 // Read these directly
1143 if(frame->get_color_model() == src_cmodel)
1146 mpeg3_read_yuvframe(fd,
1147 (char*)frame->get_y(),
1148 (char*)frame->get_u(),
1149 (char*)frame->get_v(),
1154 file->current_layer);
1158 // Process through temp frame
1162 mpeg3_read_yuvframe_ptr(fd,
1166 file->current_layer);
1170 cmodel_transfer(frame->get_rows(),
1187 frame->get_color_model(),
1201 void FileMPEG::to_streamchannel(int channel, int &stream_out, int &channel_out)
1203 for(stream_out = 0, channel_out = file->current_channel;
1204 stream_out < mpeg3_total_astreams(fd) &&
1205 channel_out >= mpeg3_audio_channels(fd, stream_out);
1206 channel_out -= mpeg3_audio_channels(fd, stream_out), stream_out++)
1210 int FileMPEG::read_samples(double *buffer, int64_t len)
1213 if(len < 0) return 0;
1215 // This is directed to a FileMPEGBuffer
1216 float *temp_float = new float[len];
1217 // Translate pure channel to a stream and a channel in the mpeg stream
1218 int stream, channel;
1219 to_streamchannel(file->current_channel, stream, channel);
1223 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
1225 mpeg3_set_sample(fd,
1226 file->current_sample,
1228 mpeg3_read_audio(fd,
1229 temp_float, /* Pointer to pre-allocated buffer of floats */
1230 0, /* Pointer to pre-allocated buffer of int16's */
1231 channel, /* Channel to decode */
1232 len, /* Number of samples to decode */
1233 stream); /* Stream containing the channel */
1236 // last_sample = file->current_sample;
1237 for(int i = 0; i < len; i++) buffer[i] = temp_float[i];
1239 delete [] temp_float;
1243 int FileMPEG::prefer_samples_float()
1248 int FileMPEG::read_samples_float(float *buffer, int64_t len)
1252 // Translate pure channel to a stream and a channel in the mpeg stream
1253 int stream, channel;
1254 to_streamchannel(file->current_channel, stream, channel);
1257 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
1259 mpeg3_set_sample(fd,
1260 file->current_sample,
1262 mpeg3_read_audio(fd,
1263 buffer, /* Pointer to pre-allocated buffer of floats */
1264 0, /* Pointer to pre-allocated buffer of int16's */
1265 channel, /* Channel to decode */
1266 len, /* Number of samples to decode */
1267 stream); /* Stream containing the channel */
1270 // last_sample = file->current_sample;
1272 //printf("FileMPEG::read_samples 100\n");
1278 char* FileMPEG::strtocompression(char *string)
1283 char* FileMPEG::compressiontostr(char *string)
1294 FileMPEGVideo::FileMPEGVideo(FileMPEG *file)
1300 if(file->asset->vmpeg_cmodel == MPEG_YUV422)
1302 mpeg2enc_init_buffers();
1303 mpeg2enc_set_w(file->asset->width);
1304 mpeg2enc_set_h(file->asset->height);
1305 mpeg2enc_set_rate(file->asset->frame_rate);
1309 FileMPEGVideo::~FileMPEGVideo()
1314 void FileMPEGVideo::run()
1316 if(file->asset->vmpeg_cmodel == MPEG_YUV422)
1318 printf("FileMPEGVideo::run ");
1319 for(int i = 0; i < file->vcommand_line.total; i++)
1320 printf("%s ", file->vcommand_line.values[i]);
1322 mpeg2enc(file->vcommand_line.total, file->vcommand_line.values);
1328 file->next_frame_lock->lock("FileMPEGVideo::run");
1331 file->next_frame_done->unlock();
1337 // YUV4 sequence header
1338 if(!file->wrote_header)
1340 file->wrote_header = 1;
1342 char string[BCTEXTLEN];
1343 char interlace_string[BCTEXTLEN];
1344 if(!file->asset->vmpeg_progressive)
1346 sprintf(interlace_string, file->asset->vmpeg_field_order ? "b" : "t");
1350 sprintf(interlace_string, "p");
1353 fprintf(file->mjpeg_out, "YUV4MPEG2 W%d H%d F%d:%d I%s A%d:%d C%s\n",
1355 file->asset->height,
1356 (int)(file->asset->frame_rate * 1001),
1359 (int)(file->asset->aspect_ratio * 1000),
1364 // YUV4 frame header
1365 fprintf(file->mjpeg_out, "FRAME\n");
1368 if(!fwrite(file->mjpeg_y, file->asset->width * file->asset->height, 1, file->mjpeg_out))
1369 file->mjpeg_error = 1;
1370 if(!fwrite(file->mjpeg_u, file->asset->width * file->asset->height / 4, 1, file->mjpeg_out))
1371 file->mjpeg_error = 1;
1372 if(!fwrite(file->mjpeg_v, file->asset->width * file->asset->height / 4, 1, file->mjpeg_out))
1373 file->mjpeg_error = 1;
1374 fflush(file->mjpeg_out);
1376 file->next_frame_done->unlock();
1378 pclose(file->mjpeg_out);
1379 file->mjpeg_out = 0;
1402 FileMPEGAudio::FileMPEGAudio(FileMPEG *file)
1406 toolame_init_buffers();
1409 FileMPEGAudio::~FileMPEGAudio()
1414 void FileMPEGAudio::run()
1416 file->toolame_result = toolame(file->acommand_line.total, file->acommand_line.values);
1426 MPEGConfigAudio::MPEGConfigAudio(BC_WindowBase *parent_window, Asset *asset)
1427 : BC_Window(PROGRAM_NAME ": Audio Compression",
1428 parent_window->get_abs_cursor_x(1),
1429 parent_window->get_abs_cursor_y(1),
1438 this->parent_window = parent_window;
1439 this->asset = asset;
1442 MPEGConfigAudio::~MPEGConfigAudio()
1446 int MPEGConfigAudio::create_objects()
1453 if(asset->format == FILE_MPEG)
1455 add_subwindow(new BC_Title(x, y, _("No options for MPEG transport stream.")));
1460 add_tool(new BC_Title(x, y, _("Layer:")));
1461 add_tool(layer = new MPEGLayer(x1, y, this));
1462 layer->create_objects();
1465 add_tool(new BC_Title(x, y, _("Kbits per second:")));
1466 add_tool(bitrate = new MPEGABitrate(x1, y, this));
1467 bitrate->create_objects();
1470 add_subwindow(new BC_OKButton(this));
1476 int MPEGConfigAudio::close_event()
1488 MPEGLayer::MPEGLayer(int x, int y, MPEGConfigAudio *gui)
1489 : BC_PopupMenu(x, y, 100, layer_to_string(gui->asset->ampeg_derivative))
1494 void MPEGLayer::create_objects()
1496 add_item(new BC_MenuItem(layer_to_string(2)));
1497 add_item(new BC_MenuItem(layer_to_string(3)));
1500 int MPEGLayer::handle_event()
1502 gui->asset->ampeg_derivative = string_to_layer(get_text());
1503 gui->bitrate->set_layer(gui->asset->ampeg_derivative);
1507 int MPEGLayer::string_to_layer(char *string)
1509 if(!strcasecmp(layer_to_string(2), string))
1511 if(!strcasecmp(layer_to_string(3), string))
1517 char* MPEGLayer::layer_to_string(int layer)
1541 MPEGABitrate::MPEGABitrate(int x, int y, MPEGConfigAudio *gui)
1545 bitrate_to_string(gui->string, gui->asset->ampeg_bitrate))
1550 void MPEGABitrate::create_objects()
1552 set_layer(gui->asset->ampeg_derivative);
1555 void MPEGABitrate::set_layer(int layer)
1557 while(total_items())
1564 add_item(new BC_MenuItem("160"));
1565 add_item(new BC_MenuItem("192"));
1566 add_item(new BC_MenuItem("224"));
1567 add_item(new BC_MenuItem("256"));
1568 add_item(new BC_MenuItem("320"));
1569 add_item(new BC_MenuItem("384"));
1573 add_item(new BC_MenuItem("8"));
1574 add_item(new BC_MenuItem("16"));
1575 add_item(new BC_MenuItem("24"));
1576 add_item(new BC_MenuItem("32"));
1577 add_item(new BC_MenuItem("40"));
1578 add_item(new BC_MenuItem("48"));
1579 add_item(new BC_MenuItem("56"));
1580 add_item(new BC_MenuItem("64"));
1581 add_item(new BC_MenuItem("80"));
1582 add_item(new BC_MenuItem("96"));
1583 add_item(new BC_MenuItem("112"));
1584 add_item(new BC_MenuItem("128"));
1585 add_item(new BC_MenuItem("144"));
1586 add_item(new BC_MenuItem("160"));
1587 add_item(new BC_MenuItem("192"));
1588 add_item(new BC_MenuItem("224"));
1589 add_item(new BC_MenuItem("256"));
1590 add_item(new BC_MenuItem("320"));
1594 int MPEGABitrate::handle_event()
1596 gui->asset->ampeg_bitrate = string_to_bitrate(get_text());
1600 int MPEGABitrate::string_to_bitrate(char *string)
1602 return atol(string);
1606 char* MPEGABitrate::bitrate_to_string(char *string, int bitrate)
1608 sprintf(string, "%d", bitrate);
1620 MPEGConfigVideo::MPEGConfigVideo(BC_WindowBase *parent_window,
1622 : BC_Window(PROGRAM_NAME ": Video Compression",
1623 parent_window->get_abs_cursor_x(1),
1624 parent_window->get_abs_cursor_y(1),
1633 this->parent_window = parent_window;
1634 this->asset = asset;
1638 MPEGConfigVideo::~MPEGConfigVideo()
1642 int MPEGConfigVideo::create_objects()
1648 if(asset->format == FILE_MPEG)
1650 add_subwindow(new BC_Title(x, y, _("No options for MPEG transport stream.")));
1654 add_subwindow(new BC_Title(x, y, _("Color model:")));
1655 add_subwindow(cmodel = new MPEGColorModel(x1, y, this));
1656 cmodel->create_objects();
1659 update_cmodel_objs();
1661 add_subwindow(new BC_OKButton(this));
1667 int MPEGConfigVideo::close_event()
1674 void MPEGConfigVideo::delete_cmodel_objs()
1679 delete fixed_bitrate;
1682 delete iframe_distance;
1683 delete pframe_distance;
1684 delete top_field_first;
1688 titles.remove_all_objects();
1692 void MPEGConfigVideo::reset_cmodel()
1700 iframe_distance = 0;
1701 pframe_distance = 0;
1702 top_field_first = 0;
1708 void MPEGConfigVideo::update_cmodel_objs()
1716 delete_cmodel_objs();
1718 if(asset->vmpeg_cmodel == MPEG_YUV420)
1720 add_subwindow(title = new BC_Title(x, y + 5, _("Format Preset:")));
1721 titles.append(title);
1722 add_subwindow(preset = new MPEGPreset(x1, y, this));
1723 preset->create_objects();
1727 add_subwindow(title = new BC_Title(x, y + 5, _("Derivative:")));
1728 titles.append(title);
1729 add_subwindow(derivative = new MPEGDerivative(x1, y, this));
1730 derivative->create_objects();
1733 add_subwindow(title = new BC_Title(x, y + 5, _("Bitrate:")));
1734 titles.append(title);
1735 add_subwindow(bitrate = new MPEGBitrate(x1, y, this));
1736 add_subwindow(fixed_bitrate = new MPEGFixedBitrate(x2, y, this));
1739 add_subwindow(title = new BC_Title(x, y, _("Quantization:")));
1740 titles.append(title);
1741 quant = new MPEGQuant(x1, y, this);
1742 quant->create_objects();
1743 add_subwindow(fixed_quant = new MPEGFixedQuant(x2, y, this));
1746 add_subwindow(title = new BC_Title(x, y, _("I frame distance:")));
1747 titles.append(title);
1748 iframe_distance = new MPEGIFrameDistance(x1, y, this);
1749 iframe_distance->create_objects();
1752 if(asset->vmpeg_cmodel == MPEG_YUV420)
1754 add_subwindow(title = new BC_Title(x, y, _("P frame distance:")));
1755 titles.append(title);
1756 pframe_distance = new MPEGPFrameDistance(x1, y, this);
1757 pframe_distance->create_objects();
1760 add_subwindow(top_field_first = new BC_CheckBox(x, y, &asset->vmpeg_field_order, _("Bottom field first")));
1764 add_subwindow(progressive = new BC_CheckBox(x, y, &asset->vmpeg_progressive, _("Progressive frames")));
1766 add_subwindow(denoise = new BC_CheckBox(x, y, &asset->vmpeg_denoise, _("Denoise")));
1768 add_subwindow(seq_codes = new BC_CheckBox(x, y, &asset->vmpeg_seq_codes, _("Sequence start codes in every GOP")));
1784 MPEGDerivative::MPEGDerivative(int x, int y, MPEGConfigVideo *gui)
1785 : BC_PopupMenu(x, y, 150, derivative_to_string(gui->asset->vmpeg_derivative))
1790 void MPEGDerivative::create_objects()
1792 add_item(new BC_MenuItem(derivative_to_string(1)));
1793 add_item(new BC_MenuItem(derivative_to_string(2)));
1796 int MPEGDerivative::handle_event()
1798 gui->asset->vmpeg_derivative = string_to_derivative(get_text());
1802 int MPEGDerivative::string_to_derivative(char *string)
1804 if(!strcasecmp(derivative_to_string(1), string))
1806 if(!strcasecmp(derivative_to_string(2), string))
1812 char* MPEGDerivative::derivative_to_string(int derivative)
1840 MPEGPreset::MPEGPreset(int x, int y, MPEGConfigVideo *gui)
1841 : BC_PopupMenu(x, y, 200, value_to_string(gui->asset->vmpeg_preset))
1846 void MPEGPreset::create_objects()
1848 for(int i = 0; i < 10; i++)
1850 add_item(new BC_MenuItem(value_to_string(i)));
1854 int MPEGPreset::handle_event()
1856 gui->asset->vmpeg_preset = string_to_value(get_text());
1860 int MPEGPreset::string_to_value(char *string)
1862 for(int i = 0; i < 10; i++)
1864 if(!strcasecmp(value_to_string(i), string))
1870 char* MPEGPreset::value_to_string(int derivative)
1874 case 0: return _("Generic MPEG-1"); break;
1875 case 1: return _("standard VCD"); break;
1876 case 2: return _("user VCD"); break;
1877 case 3: return _("Generic MPEG-2"); break;
1878 case 4: return _("standard SVCD"); break;
1879 case 5: return _("user SVCD"); break;
1880 case 6: return _("VCD Still sequence"); break;
1881 case 7: return _("SVCD Still sequence"); break;
1882 case 8: return _("DVD NAV"); break;
1883 case 9: return _("DVD"); break;
1884 default: return _("Generic MPEG-1"); break;
1898 MPEGBitrate::MPEGBitrate(int x, int y, MPEGConfigVideo *gui)
1899 : BC_TextBox(x, y, 100, 1, gui->asset->vmpeg_bitrate)
1905 int MPEGBitrate::handle_event()
1907 gui->asset->vmpeg_bitrate = atol(get_text());
1915 MPEGQuant::MPEGQuant(int x, int y, MPEGConfigVideo *gui)
1916 : BC_TumbleTextBox(gui,
1917 (int64_t)gui->asset->vmpeg_quantization,
1927 int MPEGQuant::handle_event()
1929 gui->asset->vmpeg_quantization = atol(get_text());
1933 MPEGFixedBitrate::MPEGFixedBitrate(int x, int y, MPEGConfigVideo *gui)
1934 : BC_Radial(x, y, gui->asset->vmpeg_fix_bitrate, _("Fixed bitrate"))
1939 int MPEGFixedBitrate::handle_event()
1942 gui->asset->vmpeg_fix_bitrate = 1;
1943 gui->fixed_quant->update(0);
1947 MPEGFixedQuant::MPEGFixedQuant(int x, int y, MPEGConfigVideo *gui)
1948 : BC_Radial(x, y, !gui->asset->vmpeg_fix_bitrate, _("Fixed quantization"))
1953 int MPEGFixedQuant::handle_event()
1956 gui->asset->vmpeg_fix_bitrate = 0;
1957 gui->fixed_bitrate->update(0);
1969 MPEGIFrameDistance::MPEGIFrameDistance(int x, int y, MPEGConfigVideo *gui)
1970 : BC_TumbleTextBox(gui,
1971 (int64_t)gui->asset->vmpeg_iframe_distance,
1981 int MPEGIFrameDistance::handle_event()
1983 gui->asset->vmpeg_iframe_distance = atoi(get_text());
1993 MPEGPFrameDistance::MPEGPFrameDistance(int x, int y, MPEGConfigVideo *gui)
1994 : BC_TumbleTextBox(gui,
1995 (int64_t)gui->asset->vmpeg_pframe_distance,
2005 int MPEGPFrameDistance::handle_event()
2007 gui->asset->vmpeg_pframe_distance = atoi(get_text());
2018 MPEGColorModel::MPEGColorModel(int x, int y, MPEGConfigVideo *gui)
2019 : BC_PopupMenu(x, y, 150, cmodel_to_string(gui->asset->vmpeg_cmodel))
2024 void MPEGColorModel::create_objects()
2026 add_item(new BC_MenuItem(cmodel_to_string(0)));
2027 add_item(new BC_MenuItem(cmodel_to_string(1)));
2030 int MPEGColorModel::handle_event()
2032 gui->asset->vmpeg_cmodel = string_to_cmodel(get_text());
2033 gui->update_cmodel_objs();
2037 int MPEGColorModel::string_to_cmodel(char *string)
2039 if(!strcasecmp(cmodel_to_string(0), string))
2041 if(!strcasecmp(cmodel_to_string(1), string))
2046 char* MPEGColorModel::cmodel_to_string(int cmodel)
2051 return _("YUV 4:2:0");
2055 return _("YUV 4:2:2");
2059 return _("YUV 4:2:0");