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)
178 "Couldn't open %s because it has an invalid table of contents version.\n"
179 "Rebuild the table of contents with mpeg3toc.",
181 MainError::show_error(string);
184 if(error == MPEG3_TOC_DATE_MISMATCH)
187 "Couldn't open %s because the table of contents date differs from the source date.\n"
188 "Rebuild the table of contents with mpeg3toc.",
190 MainError::show_error(string);
196 // Determine if the file needs a table of contents and create one if needed.
197 // If it has video it must be scanned since video has keyframes.
198 if(mpeg3_total_vstreams(fd))
200 if(create_index()) return 1;
203 mpeg3_set_cpus(fd, file->cpus);
205 asset->audio_data = mpeg3_has_audio(fd);
206 if(asset->audio_data)
209 for(int i = 0; i < mpeg3_total_astreams(fd); i++)
211 asset->channels += mpeg3_audio_channels(fd, i);
213 if(!asset->sample_rate)
214 asset->sample_rate = mpeg3_sample_rate(fd, 0);
215 asset->audio_length = mpeg3_audio_samples(fd, 0);
218 asset->video_data = mpeg3_has_video(fd);
219 if(asset->video_data)
221 asset->layers = mpeg3_total_vstreams(fd);
222 asset->width = mpeg3_video_width(fd, 0);
223 asset->height = mpeg3_video_height(fd, 0);
224 asset->interlace_mode = BC_ILACE_MODE_UNDETECTED; // TODO: (to do this, start at hvirtualcvs/libmpeg3/headers.c
225 // and find out how to decode info from the header)
226 asset->video_length = mpeg3_video_frames(fd, 0);
227 asset->vmpeg_cmodel =
228 (mpeg3_colormodel(fd, 0) == MPEG3_YUV422P) ? MPEG_YUV422 : MPEG_YUV420;
229 if(!asset->frame_rate)
230 asset->frame_rate = mpeg3_frame_rate(fd, 0);
233 //printf("FileMPEG::open %d\n", file->playback_subtitle);
234 if(file->playback_subtitle >= 0)
235 mpeg3_show_subtitle(fd, file->playback_subtitle);
242 if(wr && asset->format == FILE_VMPEG)
244 // Heroine Virtual encoder
245 if(asset->vmpeg_cmodel == MPEG_YUV422)
247 char bitrate_string[BCTEXTLEN];
248 char quant_string[BCTEXTLEN];
249 char iframe_string[BCTEXTLEN];
251 sprintf(bitrate_string, "%d", asset->vmpeg_bitrate);
252 sprintf(quant_string, "%d", asset->vmpeg_quantization);
253 sprintf(iframe_string, "%d", asset->vmpeg_iframe_distance);
255 // Construct command line
258 append_vcommand_line("mpeg2enc");
261 if(asset->aspect_ratio > 0)
263 append_vcommand_line("-a");
264 if(EQUIV(asset->aspect_ratio, 1))
265 append_vcommand_line("1");
267 if(EQUIV(asset->aspect_ratio, 1.333))
268 append_vcommand_line("2");
270 if(EQUIV(asset->aspect_ratio, 1.777))
271 append_vcommand_line("3");
273 if(EQUIV(asset->aspect_ratio, 2.11))
274 append_vcommand_line("4");
277 append_vcommand_line(asset->vmpeg_derivative == 1 ? "-1" : "");
278 append_vcommand_line(asset->vmpeg_cmodel == MPEG_YUV422 ? "-422" : "");
279 if(asset->vmpeg_fix_bitrate)
281 append_vcommand_line("--cbr -b");
282 append_vcommand_line(bitrate_string);
286 append_vcommand_line("-q");
287 append_vcommand_line(quant_string);
289 append_vcommand_line(!asset->vmpeg_fix_bitrate ? quant_string : "");
290 append_vcommand_line("-n");
291 append_vcommand_line(iframe_string);
292 append_vcommand_line(asset->vmpeg_progressive ? "-p" : "");
293 append_vcommand_line(asset->vmpeg_denoise ? "-d" : "");
294 append_vcommand_line(file->cpus <= 1 ? "-u" : "");
295 append_vcommand_line(asset->vmpeg_seq_codes ? "-g" : "");
296 append_vcommand_line(asset->path);
298 video_out = new FileMPEGVideo(this);
303 // mjpegtools encoder
305 char string[BCTEXTLEN];
306 sprintf(mjpeg_command, MJPEG_EXE);
308 // Must disable interlacing if MPEG-1
309 switch (asset->vmpeg_preset)
311 case 0: asset->vmpeg_progressive = 1; break;
312 case 1: asset->vmpeg_progressive = 1; break;
313 case 2: asset->vmpeg_progressive = 1; break;
318 // The current usage of mpeg2enc requires bitrate of 0 when quantization is fixed and
319 // quantization of 1 when bitrate is fixed. Perfectly intuitive.
320 if(asset->vmpeg_fix_bitrate)
322 sprintf(string, " -b %d -q 1", asset->vmpeg_bitrate / 1000);
326 sprintf(string, " -b 0 -q %d", asset->vmpeg_quantization);
328 strcat(mjpeg_command, string);
336 int aspect_ratio_code = -1;
337 if(asset->aspect_ratio > 0)
339 for(int i = 0; i < sizeof(aspect_ratio_codes) / sizeof(double); i++)
341 if(EQUIV(aspect_ratio_codes[i], asset->aspect_ratio))
343 aspect_ratio_code = i;
348 if(aspect_ratio_code < 0)
350 printf("FileMPEG::open_file: Unsupported aspect ratio %f\n", asset->aspect_ratio);
351 aspect_ratio_code = 2;
353 sprintf(string, " -a %d", aspect_ratio_code);
354 strcat(mjpeg_command, string);
362 int frame_rate_code = -1;
363 for(int i = 1; sizeof(frame_rate_codes) / sizeof(double); ++i)
365 if(EQUIV(asset->frame_rate, frame_rate_codes[i]))
371 if(frame_rate_code < 0)
374 printf("FileMPEG::open_file: Unsupported frame rate %f\n", asset->frame_rate);
376 sprintf(string, " -F %d", frame_rate_code);
377 strcat(mjpeg_command, string);
383 strcat(mjpeg_command,
384 asset->vmpeg_progressive ? " -I 0" : " -I 1");
388 sprintf(string, " -M %d", file->cpus);
389 strcat(mjpeg_command, string);
392 if(!asset->vmpeg_progressive)
394 strcat(mjpeg_command, asset->vmpeg_field_order ? " -z b" : " -z t");
398 sprintf(string, " -f %d", asset->vmpeg_preset);
399 strcat(mjpeg_command, string);
402 sprintf(string, " -g %d -G %d", asset->vmpeg_iframe_distance, asset->vmpeg_iframe_distance);
403 strcat(mjpeg_command, string);
406 if(asset->vmpeg_seq_codes) strcat(mjpeg_command, " -s");
409 sprintf(string, " -R %d", CLAMP(asset->vmpeg_pframe_distance, 0, 2));
410 strcat(mjpeg_command, string);
412 sprintf(string, " -o '%s'", asset->path);
413 strcat(mjpeg_command, string);
417 printf("FileMPEG::open_file: Running %s\n", mjpeg_command);
418 if(!(mjpeg_out = popen(mjpeg_command, "w")))
420 perror("FileMPEG::open_file");
423 video_out = new FileMPEGVideo(this);
428 if(wr && asset->format == FILE_AMPEG)
430 char command_line[BCTEXTLEN];
431 char encoder_string[BCTEXTLEN];
432 char argument_string[BCTEXTLEN];
434 //printf("FileMPEG::open_file 1 %d\n", asset->ampeg_derivative);
435 encoder_string[0] = 0;
437 if(asset->ampeg_derivative == 2)
439 char string[BCTEXTLEN];
440 append_acommand_line("toolame");
441 append_acommand_line("-m");
442 append_acommand_line((asset->channels >= 2) ? "j" : "m");
443 sprintf(string, "%f", (float)asset->sample_rate / 1000);
444 append_acommand_line("-s");
445 append_acommand_line(string);
446 sprintf(string, "%d", asset->ampeg_bitrate);
447 append_acommand_line("-b");
448 append_acommand_line(string);
449 append_acommand_line("-");
450 append_acommand_line(asset->path);
452 audio_out = new FileMPEGAudio(this);
456 if(asset->ampeg_derivative == 3)
458 lame_global = lame_init();
459 lame_set_brate(lame_global, asset->ampeg_bitrate / 1000);
460 lame_set_quality(lame_global, 0);
461 lame_set_in_samplerate(lame_global,
463 lame_set_num_channels(lame_global,
465 if((result = lame_init_params(lame_global)) < 0)
467 printf(_("encode: lame_init_params returned %d\n"), result);
468 lame_close(lame_global);
472 if(!(lame_fd = fopen(asset->path, "w")))
474 perror("FileMPEG::open_file");
475 lame_close(lame_global);
482 printf("FileMPEG::open_file: ampeg_derivative=%d\n", asset->ampeg_derivative);
487 // Transport stream for DVB capture
490 if(!(dvb_out = fopen(asset->path, "w")))
492 perror("FileMPEG::open_file");
511 int FileMPEG::create_index()
513 // Calculate TOC path
514 char index_filename[BCTEXTLEN];
515 char source_filename[BCTEXTLEN];
516 IndexFile::get_index_filename(source_filename,
517 file->preferences->index_directory,
520 char *ptr = strrchr(index_filename, '.');
525 // File is a table of contents.
526 if(fd && mpeg3_has_toc(fd)) return 0;
528 sprintf(ptr, ".toc");
532 // Test existing copy of TOC
533 if((fd = mpeg3_open(index_filename, &error)))
538 // Create progress window.
539 // This gets around the fact that MWindowGUI is locked.
540 char progress_title[BCTEXTLEN];
541 char string[BCTEXTLEN];
542 sprintf(progress_title, "Creating %s\n", index_filename);
544 mpeg3_t *index_file = mpeg3_start_toc(asset->path, index_filename, &total_bytes);
545 struct timeval new_time;
546 struct timeval prev_time;
547 struct timeval start_time;
548 struct timeval current_time;
549 gettimeofday(&prev_time, 0);
550 gettimeofday(&start_time, 0);
552 BC_ProgressBox *progress = new BC_ProgressBox(-1,
560 int64_t bytes_processed;
561 mpeg3_do_toc(index_file, &bytes_processed);
562 gettimeofday(&new_time, 0);
564 if(new_time.tv_sec - prev_time.tv_sec >= 1)
566 gettimeofday(¤t_time, 0);
567 int64_t elapsed_seconds = current_time.tv_sec - start_time.tv_sec;
568 int64_t total_seconds = elapsed_seconds * total_bytes / bytes_processed;
569 int64_t eta = total_seconds - elapsed_seconds;
570 progress->update(bytes_processed, 1);
576 progress->update_title(string, 1);
577 // fprintf(stderr, "ETA: %dm%ds \r",
578 // bytes_processed * 100 / total_bytes,
582 prev_time = new_time;
584 if(bytes_processed >= total_bytes) break;
585 if(progress->is_cancelled())
592 mpeg3_stop_toc(index_file);
594 progress->stop_progress();
600 remove(index_filename);
604 // Fix date to date of source if success
608 if(fd) mpeg3_close(fd);
614 // Reopen file from index path instead of asset path.
617 if(!(fd = mpeg3_open(index_filename, &error)))
633 void FileMPEG::append_vcommand_line(const char *string)
637 char *argv = strdup(string);
638 vcommand_line.append(argv);
642 void FileMPEG::append_acommand_line(const char *string)
646 char *argv = strdup(string);
647 acommand_line.append(argv);
652 int FileMPEG::close_file()
655 next_frame_lock->unlock();
664 // End of sequence signal
665 if(file->asset->vmpeg_cmodel == MPEG_YUV422)
667 mpeg2enc_set_input_buffers(1, 0, 0, 0);
673 vcommand_line.remove_all_objects();
674 acommand_line.remove_all_objects();
678 toolame_send_buffer(0, 0);
684 lame_close(lame_global);
686 if(temp_frame) delete temp_frame;
687 if(toolame_temp) delete [] toolame_temp;
689 if(lame_temp[0]) delete [] lame_temp[0];
690 if(lame_temp[1]) delete [] lame_temp[1];
691 if(lame_output) delete [] lame_output;
692 if(lame_fd) fclose(lame_fd);
694 if(mjpeg_out) fclose(mjpeg_out);
702 FileBase::close_file();
706 int FileMPEG::get_best_colormodel(Asset *asset, int driver)
708 //printf("FileMPEG::get_best_colormodel 1\n");
713 if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
714 if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
716 case PLAYBACK_X11_XV:
717 case PLAYBACK_ASYNCHRONOUS:
718 if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
719 if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
721 case PLAYBACK_X11_GL:
728 case PLAYBACK_DV1394:
729 case PLAYBACK_FIREWIRE:
734 if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
735 if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
741 case CAPTURE_FIREWIRE:
742 case CAPTURE_IEC61883:
746 //printf("FileMPEG::get_best_colormodel 100\n");
749 int FileMPEG::colormodel_supported(int colormodel)
754 int FileMPEG::get_index(char *index_path)
759 // Convert the index tables from tracks to channels.
760 if(mpeg3_index_tracks(fd))
762 // Calculate size of buffer needed for all channels
764 for(int i = 0; i < mpeg3_index_tracks(fd); i++)
766 buffer_size += mpeg3_index_size(fd, i) *
767 mpeg3_index_channels(fd, i) *
771 asset->index_buffer = new float[buffer_size];
773 // Size of index buffer in floats
774 int current_offset = 0;
775 // Current asset channel
776 int current_channel = 0;
777 asset->index_zoom = mpeg3_index_zoom(fd);
778 asset->index_offsets = new int64_t[asset->channels];
779 asset->index_sizes = new int64_t[asset->channels];
780 for(int i = 0; i < mpeg3_index_tracks(fd); i++)
782 for(int j = 0; j < mpeg3_index_channels(fd, i); j++)
784 asset->index_offsets[current_channel] = current_offset;
785 asset->index_sizes[current_channel] = mpeg3_index_size(fd, i) * 2;
786 memcpy(asset->index_buffer + current_offset,
787 mpeg3_index_data(fd, i, j),
788 mpeg3_index_size(fd, i) * sizeof(float) * 2);
790 current_offset += mpeg3_index_size(fd, i) * 2;
796 asset->index_bytes = fs.get_size(asset->path);
798 asset->write_index(index_path, buffer_size * sizeof(float));
799 delete [] asset->index_buffer;
808 int FileMPEG::can_copy_from(Edit *edit, int64_t position)
814 int FileMPEG::set_audio_position(int64_t sample)
820 to_streamchannel(file->current_channel, stream, channel);
822 //printf("FileMPEG::set_audio_position %d %d %d\n", sample, mpeg3_get_sample(fd, stream), last_sample);
823 if(sample != mpeg3_get_sample(fd, stream) &&
824 sample != last_sample)
826 if(sample >= 0 && sample < asset->audio_length)
828 //printf("FileMPEG::set_audio_position seeking stream %d\n", sample);
829 return mpeg3_set_sample(fd, sample, stream);
838 int FileMPEG::set_video_position(int64_t x)
841 if(x >= 0 && x < asset->video_length)
843 //printf("FileMPEG::set_video_position 1 %lld\n", x);
844 mpeg3_set_frame(fd, x, file->current_layer);
850 int64_t FileMPEG::get_memory_usage()
854 int64_t result = mpeg3_memory_usage(fd);
861 int FileMPEG::write_samples(double **buffer, int64_t len)
865 //printf("FileMPEG::write_samples 1\n");
866 if(asset->ampeg_derivative == 2)
869 int channels = MIN(asset->channels, 2);
870 int64_t audio_size = len * channels * 2;
871 if(toolame_allocation < audio_size)
873 if(toolame_temp) delete [] toolame_temp;
874 toolame_temp = new unsigned char[audio_size];
875 toolame_allocation = audio_size;
878 for(int i = 0; i < channels; i++)
880 int16_t *output = ((int16_t*)toolame_temp) + i;
881 double *input = buffer[i];
882 for(int j = 0; j < len; j++)
884 int sample = (int)(*input * 0x7fff);
885 *output = (int16_t)(CLIP(sample, -0x8000, 0x7fff));
890 result = toolame_send_buffer((char*)toolame_temp, audio_size);
893 if(asset->ampeg_derivative == 3)
895 int channels = MIN(asset->channels, 2);
896 int64_t audio_size = len * channels;
897 if(!lame_global) return 1;
898 if(!lame_fd) return 1;
899 if(lame_allocation < audio_size)
901 if(lame_temp[0]) delete [] lame_temp[0];
902 if(lame_temp[1]) delete [] lame_temp[1];
903 lame_temp[0] = new float[audio_size];
904 lame_temp[1] = new float[audio_size];
905 lame_allocation = audio_size;
908 if(lame_output_allocation < audio_size * 4)
910 if(lame_output) delete [] lame_output;
911 lame_output_allocation = audio_size * 4;
912 lame_output = new char[lame_output_allocation];
915 for(int i = 0; i < channels; i++)
917 float *output = lame_temp[i];
918 double *input = buffer[i];
919 for(int j = 0; j < len; j++)
921 *output++ = *input++ * (float)32768;
925 result = lame_encode_buffer_float(lame_global,
927 (channels > 1) ? lame_temp[1] : lame_temp[0],
929 (unsigned char*)lame_output,
930 lame_output_allocation);
933 char *real_output = lame_output;
937 for(int i = 0; i < bytes; i++)
940 real_output = &lame_output[i];
946 if(bytes > 0 && lame_started)
948 result = !fwrite(real_output, 1, bytes, lame_fd);
950 perror("FileMPEG::write_samples");
962 int FileMPEG::write_frames(VFrame ***frames, int len)
968 int temp_w = (int)((asset->width + 15) / 16) * 16;
973 (asset->vmpeg_cmodel == MPEG_YUV420) ? BC_YUV420P : BC_YUV422P;
976 // Height depends on progressiveness
977 if(asset->vmpeg_progressive || asset->vmpeg_derivative == 1)
978 temp_h = (int)((asset->height + 15) / 16) * 16;
980 temp_h = (int)((asset->height + 31) / 32) * 32;
982 //printf("FileMPEG::write_frames 1\n");
984 // Only 1 layer is supported in MPEG output
985 for(int i = 0; i < 1; i++)
987 for(int j = 0; j < len && !result; j++)
989 VFrame *frame = frames[i][j];
993 if(asset->vmpeg_cmodel == MPEG_YUV422)
995 if(frame->get_w() == temp_w &&
996 frame->get_h() == temp_h &&
997 frame->get_color_model() == output_cmodel)
999 mpeg2enc_set_input_buffers(0,
1000 (char*)frame->get_y(),
1001 (char*)frame->get_u(),
1002 (char*)frame->get_v());
1007 (temp_frame->get_w() != temp_w ||
1008 temp_frame->get_h() != temp_h ||
1009 temp_frame->get_color_model() || output_cmodel))
1018 temp_frame = new VFrame(0,
1024 cmodel_transfer(temp_frame->get_rows(),
1026 temp_frame->get_y(),
1027 temp_frame->get_u(),
1028 temp_frame->get_v(),
1040 frame->get_color_model(),
1041 temp_frame->get_color_model(),
1046 mpeg2enc_set_input_buffers(0,
1047 (char*)temp_frame->get_y(),
1048 (char*)temp_frame->get_u(),
1049 (char*)temp_frame->get_v());
1054 // MJPEG uses the same dimensions as the input
1055 if(frame->get_color_model() == output_cmodel)
1057 mjpeg_y = frame->get_y();
1058 mjpeg_u = frame->get_u();
1059 mjpeg_v = frame->get_v();
1065 temp_frame = new VFrame(0,
1071 cmodel_transfer(temp_frame->get_rows(),
1073 temp_frame->get_y(),
1074 temp_frame->get_u(),
1075 temp_frame->get_v(),
1087 frame->get_color_model(),
1088 temp_frame->get_color_model(),
1093 mjpeg_y = temp_frame->get_y();
1094 mjpeg_u = temp_frame->get_u();
1095 mjpeg_v = temp_frame->get_v();
1101 next_frame_lock->unlock();
1102 next_frame_done->lock("FileMPEG::write_frames");
1103 if(mjpeg_error) result = 1;
1119 int FileMPEG::read_frame(VFrame *frame)
1125 // printf("FileMPEG::read_frame\n");
1126 // frame->dump_stacks();
1127 // frame->dump_params();
1129 if(mpeg3_colormodel(fd, 0) == MPEG3_YUV420P)
1130 src_cmodel = BC_YUV420P;
1132 if(mpeg3_colormodel(fd, 0) == MPEG3_YUV422P)
1133 src_cmodel = BC_YUV422P;
1135 switch(frame->get_color_model())
1139 case MPEG3_BGRA8888:
1141 case MPEG3_RGBA8888:
1142 case MPEG3_RGBA16161616:
1144 mpeg3_read_frame(fd,
1145 frame->get_rows(), /* Array of pointers to the start of each output row */
1146 0, /* Location in input frame to take picture */
1150 asset->width, /* Dimensions of output_rows */
1152 frame->get_color_model(), /* One of the color model #defines */
1153 file->current_layer);
1159 // Read these directly
1160 if(frame->get_color_model() == src_cmodel)
1163 mpeg3_read_yuvframe(fd,
1164 (char*)frame->get_y(),
1165 (char*)frame->get_u(),
1166 (char*)frame->get_v(),
1171 file->current_layer);
1175 // Process through temp frame
1179 mpeg3_read_yuvframe_ptr(fd,
1183 file->current_layer);
1187 cmodel_transfer(frame->get_rows(),
1204 frame->get_color_model(),
1218 void FileMPEG::to_streamchannel(int channel, int &stream_out, int &channel_out)
1220 for(stream_out = 0, channel_out = file->current_channel;
1221 stream_out < mpeg3_total_astreams(fd) &&
1222 channel_out >= mpeg3_audio_channels(fd, stream_out);
1223 channel_out -= mpeg3_audio_channels(fd, stream_out), stream_out++)
1227 int FileMPEG::read_samples(double *buffer, int64_t len)
1230 if(len < 0) return 0;
1232 // This is directed to a FileMPEGBuffer
1233 float *temp_float = new float[len];
1234 // Translate pure channel to a stream and a channel in the mpeg stream
1235 int stream, channel;
1236 to_streamchannel(file->current_channel, stream, channel);
1240 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
1242 mpeg3_set_sample(fd,
1243 file->current_sample,
1245 mpeg3_read_audio(fd,
1246 temp_float, /* Pointer to pre-allocated buffer of floats */
1247 0, /* Pointer to pre-allocated buffer of int16's */
1248 channel, /* Channel to decode */
1249 len, /* Number of samples to decode */
1250 stream); /* Stream containing the channel */
1253 // last_sample = file->current_sample;
1254 for(int i = 0; i < len; i++) buffer[i] = temp_float[i];
1256 delete [] temp_float;
1260 int FileMPEG::prefer_samples_float()
1265 int FileMPEG::read_samples_float(float *buffer, int64_t len)
1269 // Translate pure channel to a stream and a channel in the mpeg stream
1270 int stream, channel;
1271 to_streamchannel(file->current_channel, stream, channel);
1274 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
1276 mpeg3_set_sample(fd,
1277 file->current_sample,
1279 mpeg3_read_audio(fd,
1280 buffer, /* Pointer to pre-allocated buffer of floats */
1281 0, /* Pointer to pre-allocated buffer of int16's */
1282 channel, /* Channel to decode */
1283 len, /* Number of samples to decode */
1284 stream); /* Stream containing the channel */
1287 // last_sample = file->current_sample;
1289 //printf("FileMPEG::read_samples 100\n");
1295 char* FileMPEG::strtocompression(char *string)
1300 char* FileMPEG::compressiontostr(char *string)
1311 FileMPEGVideo::FileMPEGVideo(FileMPEG *file)
1317 if(file->asset->vmpeg_cmodel == MPEG_YUV422)
1319 mpeg2enc_init_buffers();
1320 mpeg2enc_set_w(file->asset->width);
1321 mpeg2enc_set_h(file->asset->height);
1322 mpeg2enc_set_rate(file->asset->frame_rate);
1326 FileMPEGVideo::~FileMPEGVideo()
1331 void FileMPEGVideo::run()
1333 if(file->asset->vmpeg_cmodel == MPEG_YUV422)
1335 printf("FileMPEGVideo::run ");
1336 for(int i = 0; i < file->vcommand_line.total; i++)
1337 printf("%s ", file->vcommand_line.values[i]);
1339 mpeg2enc(file->vcommand_line.total, file->vcommand_line.values);
1345 file->next_frame_lock->lock("FileMPEGVideo::run");
1348 file->next_frame_done->unlock();
1354 // YUV4 sequence header
1355 if(!file->wrote_header)
1357 file->wrote_header = 1;
1359 char string[BCTEXTLEN];
1360 char interlace_string[BCTEXTLEN];
1361 if(!file->asset->vmpeg_progressive)
1363 sprintf(interlace_string, file->asset->vmpeg_field_order ? "b" : "t");
1367 sprintf(interlace_string, "p");
1370 fprintf(file->mjpeg_out, "YUV4MPEG2 W%d H%d F%d:%d I%s A%d:%d C%s\n",
1372 file->asset->height,
1373 (int)(file->asset->frame_rate * 1001),
1376 (int)(file->asset->aspect_ratio * 1000),
1381 // YUV4 frame header
1382 fprintf(file->mjpeg_out, "FRAME\n");
1385 if(!fwrite(file->mjpeg_y, file->asset->width * file->asset->height, 1, file->mjpeg_out))
1386 file->mjpeg_error = 1;
1387 if(!fwrite(file->mjpeg_u, file->asset->width * file->asset->height / 4, 1, file->mjpeg_out))
1388 file->mjpeg_error = 1;
1389 if(!fwrite(file->mjpeg_v, file->asset->width * file->asset->height / 4, 1, file->mjpeg_out))
1390 file->mjpeg_error = 1;
1391 fflush(file->mjpeg_out);
1393 file->next_frame_done->unlock();
1395 pclose(file->mjpeg_out);
1396 file->mjpeg_out = 0;
1419 FileMPEGAudio::FileMPEGAudio(FileMPEG *file)
1423 toolame_init_buffers();
1426 FileMPEGAudio::~FileMPEGAudio()
1431 void FileMPEGAudio::run()
1433 file->toolame_result = toolame(file->acommand_line.total, file->acommand_line.values);
1443 MPEGConfigAudio::MPEGConfigAudio(BC_WindowBase *parent_window, Asset *asset)
1444 : BC_Window(PROGRAM_NAME ": Audio Compression",
1445 parent_window->get_abs_cursor_x(1),
1446 parent_window->get_abs_cursor_y(1),
1455 this->parent_window = parent_window;
1456 this->asset = asset;
1459 MPEGConfigAudio::~MPEGConfigAudio()
1463 int MPEGConfigAudio::create_objects()
1470 if(asset->format == FILE_MPEG)
1472 add_subwindow(new BC_Title(x, y, _("No options for MPEG transport stream.")));
1477 add_tool(new BC_Title(x, y, _("Layer:")));
1478 add_tool(layer = new MPEGLayer(x1, y, this));
1479 layer->create_objects();
1482 add_tool(new BC_Title(x, y, _("Kbits per second:")));
1483 add_tool(bitrate = new MPEGABitrate(x1, y, this));
1484 bitrate->create_objects();
1487 add_subwindow(new BC_OKButton(this));
1493 int MPEGConfigAudio::close_event()
1505 MPEGLayer::MPEGLayer(int x, int y, MPEGConfigAudio *gui)
1506 : BC_PopupMenu(x, y, 100, layer_to_string(gui->asset->ampeg_derivative))
1511 void MPEGLayer::create_objects()
1513 add_item(new BC_MenuItem(layer_to_string(2)));
1514 add_item(new BC_MenuItem(layer_to_string(3)));
1517 int MPEGLayer::handle_event()
1519 gui->asset->ampeg_derivative = string_to_layer(get_text());
1520 gui->bitrate->set_layer(gui->asset->ampeg_derivative);
1524 int MPEGLayer::string_to_layer(char *string)
1526 if(!strcasecmp(layer_to_string(2), string))
1528 if(!strcasecmp(layer_to_string(3), string))
1534 char* MPEGLayer::layer_to_string(int layer)
1558 MPEGABitrate::MPEGABitrate(int x, int y, MPEGConfigAudio *gui)
1562 bitrate_to_string(gui->string, gui->asset->ampeg_bitrate))
1567 void MPEGABitrate::create_objects()
1569 set_layer(gui->asset->ampeg_derivative);
1572 void MPEGABitrate::set_layer(int layer)
1574 while(total_items())
1581 add_item(new BC_MenuItem("160"));
1582 add_item(new BC_MenuItem("192"));
1583 add_item(new BC_MenuItem("224"));
1584 add_item(new BC_MenuItem("256"));
1585 add_item(new BC_MenuItem("320"));
1586 add_item(new BC_MenuItem("384"));
1590 add_item(new BC_MenuItem("8"));
1591 add_item(new BC_MenuItem("16"));
1592 add_item(new BC_MenuItem("24"));
1593 add_item(new BC_MenuItem("32"));
1594 add_item(new BC_MenuItem("40"));
1595 add_item(new BC_MenuItem("48"));
1596 add_item(new BC_MenuItem("56"));
1597 add_item(new BC_MenuItem("64"));
1598 add_item(new BC_MenuItem("80"));
1599 add_item(new BC_MenuItem("96"));
1600 add_item(new BC_MenuItem("112"));
1601 add_item(new BC_MenuItem("128"));
1602 add_item(new BC_MenuItem("144"));
1603 add_item(new BC_MenuItem("160"));
1604 add_item(new BC_MenuItem("192"));
1605 add_item(new BC_MenuItem("224"));
1606 add_item(new BC_MenuItem("256"));
1607 add_item(new BC_MenuItem("320"));
1611 int MPEGABitrate::handle_event()
1613 gui->asset->ampeg_bitrate = string_to_bitrate(get_text());
1617 int MPEGABitrate::string_to_bitrate(char *string)
1619 return atol(string);
1623 char* MPEGABitrate::bitrate_to_string(char *string, int bitrate)
1625 sprintf(string, "%d", bitrate);
1637 MPEGConfigVideo::MPEGConfigVideo(BC_WindowBase *parent_window,
1639 : BC_Window(PROGRAM_NAME ": Video Compression",
1640 parent_window->get_abs_cursor_x(1),
1641 parent_window->get_abs_cursor_y(1),
1650 this->parent_window = parent_window;
1651 this->asset = asset;
1655 MPEGConfigVideo::~MPEGConfigVideo()
1659 int MPEGConfigVideo::create_objects()
1665 if(asset->format == FILE_MPEG)
1667 add_subwindow(new BC_Title(x, y, _("No options for MPEG transport stream.")));
1671 add_subwindow(new BC_Title(x, y, _("Color model:")));
1672 add_subwindow(cmodel = new MPEGColorModel(x1, y, this));
1673 cmodel->create_objects();
1676 update_cmodel_objs();
1678 add_subwindow(new BC_OKButton(this));
1684 int MPEGConfigVideo::close_event()
1691 void MPEGConfigVideo::delete_cmodel_objs()
1696 delete fixed_bitrate;
1699 delete iframe_distance;
1700 delete pframe_distance;
1701 delete top_field_first;
1705 titles.remove_all_objects();
1709 void MPEGConfigVideo::reset_cmodel()
1717 iframe_distance = 0;
1718 pframe_distance = 0;
1719 top_field_first = 0;
1725 void MPEGConfigVideo::update_cmodel_objs()
1733 delete_cmodel_objs();
1735 if(asset->vmpeg_cmodel == MPEG_YUV420)
1737 add_subwindow(title = new BC_Title(x, y + 5, _("Format Preset:")));
1738 titles.append(title);
1739 add_subwindow(preset = new MPEGPreset(x1, y, this));
1740 preset->create_objects();
1744 add_subwindow(title = new BC_Title(x, y + 5, _("Derivative:")));
1745 titles.append(title);
1746 add_subwindow(derivative = new MPEGDerivative(x1, y, this));
1747 derivative->create_objects();
1750 add_subwindow(title = new BC_Title(x, y + 5, _("Bitrate:")));
1751 titles.append(title);
1752 add_subwindow(bitrate = new MPEGBitrate(x1, y, this));
1753 add_subwindow(fixed_bitrate = new MPEGFixedBitrate(x2, y, this));
1756 add_subwindow(title = new BC_Title(x, y, _("Quantization:")));
1757 titles.append(title);
1758 quant = new MPEGQuant(x1, y, this);
1759 quant->create_objects();
1760 add_subwindow(fixed_quant = new MPEGFixedQuant(x2, y, this));
1763 add_subwindow(title = new BC_Title(x, y, _("I frame distance:")));
1764 titles.append(title);
1765 iframe_distance = new MPEGIFrameDistance(x1, y, this);
1766 iframe_distance->create_objects();
1769 if(asset->vmpeg_cmodel == MPEG_YUV420)
1771 add_subwindow(title = new BC_Title(x, y, _("P frame distance:")));
1772 titles.append(title);
1773 pframe_distance = new MPEGPFrameDistance(x1, y, this);
1774 pframe_distance->create_objects();
1777 add_subwindow(top_field_first = new BC_CheckBox(x, y, &asset->vmpeg_field_order, _("Bottom field first")));
1781 add_subwindow(progressive = new BC_CheckBox(x, y, &asset->vmpeg_progressive, _("Progressive frames")));
1783 add_subwindow(denoise = new BC_CheckBox(x, y, &asset->vmpeg_denoise, _("Denoise")));
1785 add_subwindow(seq_codes = new BC_CheckBox(x, y, &asset->vmpeg_seq_codes, _("Sequence start codes in every GOP")));
1801 MPEGDerivative::MPEGDerivative(int x, int y, MPEGConfigVideo *gui)
1802 : BC_PopupMenu(x, y, 150, derivative_to_string(gui->asset->vmpeg_derivative))
1807 void MPEGDerivative::create_objects()
1809 add_item(new BC_MenuItem(derivative_to_string(1)));
1810 add_item(new BC_MenuItem(derivative_to_string(2)));
1813 int MPEGDerivative::handle_event()
1815 gui->asset->vmpeg_derivative = string_to_derivative(get_text());
1819 int MPEGDerivative::string_to_derivative(char *string)
1821 if(!strcasecmp(derivative_to_string(1), string))
1823 if(!strcasecmp(derivative_to_string(2), string))
1829 char* MPEGDerivative::derivative_to_string(int derivative)
1857 MPEGPreset::MPEGPreset(int x, int y, MPEGConfigVideo *gui)
1858 : BC_PopupMenu(x, y, 200, value_to_string(gui->asset->vmpeg_preset))
1863 void MPEGPreset::create_objects()
1865 for(int i = 0; i < 10; i++)
1867 add_item(new BC_MenuItem(value_to_string(i)));
1871 int MPEGPreset::handle_event()
1873 gui->asset->vmpeg_preset = string_to_value(get_text());
1877 int MPEGPreset::string_to_value(char *string)
1879 for(int i = 0; i < 10; i++)
1881 if(!strcasecmp(value_to_string(i), string))
1887 char* MPEGPreset::value_to_string(int derivative)
1891 case 0: return _("Generic MPEG-1"); break;
1892 case 1: return _("standard VCD"); break;
1893 case 2: return _("user VCD"); break;
1894 case 3: return _("Generic MPEG-2"); break;
1895 case 4: return _("standard SVCD"); break;
1896 case 5: return _("user SVCD"); break;
1897 case 6: return _("VCD Still sequence"); break;
1898 case 7: return _("SVCD Still sequence"); break;
1899 case 8: return _("DVD NAV"); break;
1900 case 9: return _("DVD"); break;
1901 default: return _("Generic MPEG-1"); break;
1915 MPEGBitrate::MPEGBitrate(int x, int y, MPEGConfigVideo *gui)
1916 : BC_TextBox(x, y, 100, 1, gui->asset->vmpeg_bitrate)
1922 int MPEGBitrate::handle_event()
1924 gui->asset->vmpeg_bitrate = atol(get_text());
1932 MPEGQuant::MPEGQuant(int x, int y, MPEGConfigVideo *gui)
1933 : BC_TumbleTextBox(gui,
1934 (int64_t)gui->asset->vmpeg_quantization,
1944 int MPEGQuant::handle_event()
1946 gui->asset->vmpeg_quantization = atol(get_text());
1950 MPEGFixedBitrate::MPEGFixedBitrate(int x, int y, MPEGConfigVideo *gui)
1951 : BC_Radial(x, y, gui->asset->vmpeg_fix_bitrate, _("Fixed bitrate"))
1956 int MPEGFixedBitrate::handle_event()
1959 gui->asset->vmpeg_fix_bitrate = 1;
1960 gui->fixed_quant->update(0);
1964 MPEGFixedQuant::MPEGFixedQuant(int x, int y, MPEGConfigVideo *gui)
1965 : BC_Radial(x, y, !gui->asset->vmpeg_fix_bitrate, _("Fixed quantization"))
1970 int MPEGFixedQuant::handle_event()
1973 gui->asset->vmpeg_fix_bitrate = 0;
1974 gui->fixed_bitrate->update(0);
1986 MPEGIFrameDistance::MPEGIFrameDistance(int x, int y, MPEGConfigVideo *gui)
1987 : BC_TumbleTextBox(gui,
1988 (int64_t)gui->asset->vmpeg_iframe_distance,
1998 int MPEGIFrameDistance::handle_event()
2000 gui->asset->vmpeg_iframe_distance = atoi(get_text());
2010 MPEGPFrameDistance::MPEGPFrameDistance(int x, int y, MPEGConfigVideo *gui)
2011 : BC_TumbleTextBox(gui,
2012 (int64_t)gui->asset->vmpeg_pframe_distance,
2022 int MPEGPFrameDistance::handle_event()
2024 gui->asset->vmpeg_pframe_distance = atoi(get_text());
2035 MPEGColorModel::MPEGColorModel(int x, int y, MPEGConfigVideo *gui)
2036 : BC_PopupMenu(x, y, 150, cmodel_to_string(gui->asset->vmpeg_cmodel))
2041 void MPEGColorModel::create_objects()
2043 add_item(new BC_MenuItem(cmodel_to_string(0)));
2044 add_item(new BC_MenuItem(cmodel_to_string(1)));
2047 int MPEGColorModel::handle_event()
2049 gui->asset->vmpeg_cmodel = string_to_cmodel(get_text());
2050 gui->update_cmodel_objs();
2054 int MPEGColorModel::string_to_cmodel(char *string)
2056 if(!strcasecmp(cmodel_to_string(0), string))
2058 if(!strcasecmp(cmodel_to_string(1), string))
2063 char* MPEGColorModel::cmodel_to_string(int cmodel)
2068 return _("YUV 4:2:0");
2072 return _("YUV 4:2:2");
2076 return _("YUV 4:2:0");