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 int FileMPEG::reset_parameters_derived()
131 toolame_allocation = 0;
138 lame_output_allocation = 0;
144 // Just create the Quicktime objects since this routine is also called
146 int FileMPEG::open_file(int rd, int wr)
156 if(!(fd = mpeg3_open(asset->path, &error)))
158 char string[BCTEXTLEN];
159 if(error == MPEG3_INVALID_TOC_VERSION)
162 "Couldn't open %s because it has an invalid table of contents version.\n"
163 "Rebuild the table of contents with mpeg3toc.",
165 MainError::show_error(string);
168 if(error == MPEG3_TOC_DATE_MISMATCH)
171 "Couldn't open %s because the table of contents date differs from the source date.\n"
172 "Rebuild the table of contents with mpeg3toc.",
174 MainError::show_error(string);
180 // Determine if the file needs a table of contents and create one if needed.
181 // If it has video it must be scanned since video has keyframes.
182 if(mpeg3_total_vstreams(fd))
184 if(create_index()) return 1;
187 mpeg3_set_cpus(fd, file->cpus);
189 asset->audio_data = mpeg3_has_audio(fd);
190 if(asset->audio_data)
193 for(int i = 0; i < mpeg3_total_astreams(fd); i++)
195 asset->channels += mpeg3_audio_channels(fd, i);
197 if(!asset->sample_rate)
198 asset->sample_rate = mpeg3_sample_rate(fd, 0);
199 asset->audio_length = mpeg3_audio_samples(fd, 0);
202 asset->video_data = mpeg3_has_video(fd);
203 if(asset->video_data)
205 asset->layers = mpeg3_total_vstreams(fd);
206 asset->width = mpeg3_video_width(fd, 0);
207 asset->height = mpeg3_video_height(fd, 0);
208 asset->interlace_mode = BC_ILACE_MODE_UNDETECTED; // TODO: (to do this, start at hvirtualcvs/libmpeg3/headers.c
209 // and find out how to decode info from the header)
210 asset->video_length = mpeg3_video_frames(fd, 0);
211 asset->vmpeg_cmodel =
212 (mpeg3_colormodel(fd, 0) == MPEG3_YUV422P) ? MPEG_YUV422 : MPEG_YUV420;
213 if(!asset->frame_rate)
214 asset->frame_rate = mpeg3_frame_rate(fd, 0);
221 if(wr && asset->format == FILE_VMPEG)
223 // Heroine Virtual encoder
224 if(asset->vmpeg_cmodel == MPEG_YUV422)
226 char bitrate_string[BCTEXTLEN];
227 char quant_string[BCTEXTLEN];
228 char iframe_string[BCTEXTLEN];
230 sprintf(bitrate_string, "%d", asset->vmpeg_bitrate);
231 sprintf(quant_string, "%d", asset->vmpeg_quantization);
232 sprintf(iframe_string, "%d", asset->vmpeg_iframe_distance);
234 // Construct command line
237 append_vcommand_line("mpeg2enc");
240 if(asset->aspect_ratio > 0)
242 append_vcommand_line("-a");
243 if(EQUIV(asset->aspect_ratio, 1))
244 append_vcommand_line("1");
246 if(EQUIV(asset->aspect_ratio, 1.333))
247 append_vcommand_line("2");
249 if(EQUIV(asset->aspect_ratio, 1.777))
250 append_vcommand_line("3");
252 if(EQUIV(asset->aspect_ratio, 2.11))
253 append_vcommand_line("4");
256 append_vcommand_line(asset->vmpeg_derivative == 1 ? "-1" : "");
257 append_vcommand_line(asset->vmpeg_cmodel == MPEG_YUV422 ? "-422" : "");
258 if(asset->vmpeg_fix_bitrate)
260 append_vcommand_line("--cbr -b");
261 append_vcommand_line(bitrate_string);
265 append_vcommand_line("-q");
266 append_vcommand_line(quant_string);
268 append_vcommand_line(!asset->vmpeg_fix_bitrate ? quant_string : "");
269 append_vcommand_line("-n");
270 append_vcommand_line(iframe_string);
271 append_vcommand_line(asset->vmpeg_progressive ? "-p" : "");
272 append_vcommand_line(asset->vmpeg_denoise ? "-d" : "");
273 append_vcommand_line(file->cpus <= 1 ? "-u" : "");
274 append_vcommand_line(asset->vmpeg_seq_codes ? "-g" : "");
275 append_vcommand_line(asset->path);
277 video_out = new FileMPEGVideo(this);
282 // mjpegtools encoder
284 char string[BCTEXTLEN];
285 sprintf(mjpeg_command, MJPEG_EXE);
287 if(asset->vmpeg_fix_bitrate)
289 sprintf(string, " --cbr -b %d", asset->vmpeg_bitrate);
293 sprintf(string, " -q %d", asset->vmpeg_quantization);
295 strcat(mjpeg_command, string);
303 int aspect_ratio_code = -1;
304 if(asset->aspect_ratio > 0)
306 for(int i = 0; i < sizeof(aspect_ratio_codes) / sizeof(double); i++)
308 if(EQUIV(aspect_ratio_codes[i], asset->aspect_ratio))
310 aspect_ratio_code = i;
315 if(aspect_ratio_code < 0)
317 printf("FileMPEG::open_file: Unsupported aspect ratio %f\n", asset->aspect_ratio);
318 aspect_ratio_code = 2;
320 sprintf(string, " -a %d", aspect_ratio_code);
321 strcat(mjpeg_command, string);
329 int frame_rate_code = -1;
330 for(int i = 1; sizeof(frame_rate_codes) / sizeof(double); ++i)
332 if(EQUIV(asset->frame_rate, frame_rate_codes[i]))
338 if(frame_rate_code < 0)
341 printf("FileMPEG::open_file: Unsupported frame rate %f\n", asset->frame_rate);
343 sprintf(string, " -F %d", frame_rate_code);
344 strcat(mjpeg_command, string);
350 strcat(mjpeg_command,
351 asset->vmpeg_progressive ? " -I 0" : " -I 1");
355 sprintf(string, " -M %d", file->cpus);
356 strcat(mjpeg_command, string);
359 if(!asset->vmpeg_progressive)
361 strcat(mjpeg_command, asset->vmpeg_field_order ? " -z b" : " -z t");
365 sprintf(string, " -f %d", asset->vmpeg_preset);
366 strcat(mjpeg_command, string);
369 sprintf(string, " -g %d -G %d", asset->vmpeg_iframe_distance, asset->vmpeg_iframe_distance);
370 strcat(mjpeg_command, string);
373 if(asset->vmpeg_seq_codes) strcat(mjpeg_command, " -s");
376 sprintf(string, " -R %d", CLAMP(asset->vmpeg_pframe_distance, 0, 2));
377 strcat(mjpeg_command, string);
379 sprintf(string, " -o '%s'", asset->path);
380 strcat(mjpeg_command, string);
384 printf("FileMPEG::open_file: Running %s\n", mjpeg_command);
385 if(!(mjpeg_out = popen(mjpeg_command, "w")))
387 perror("FileMPEG::open_file");
390 video_out = new FileMPEGVideo(this);
395 if(wr && asset->format == FILE_AMPEG)
397 char command_line[BCTEXTLEN];
398 char encoder_string[BCTEXTLEN];
399 char argument_string[BCTEXTLEN];
401 //printf("FileMPEG::open_file 1 %d\n", asset->ampeg_derivative);
402 encoder_string[0] = 0;
404 if(asset->ampeg_derivative == 2)
406 char string[BCTEXTLEN];
407 append_acommand_line("toolame");
408 append_acommand_line("-m");
409 append_acommand_line((asset->channels >= 2) ? "j" : "m");
410 sprintf(string, "%f", (float)asset->sample_rate / 1000);
411 append_acommand_line("-s");
412 append_acommand_line(string);
413 sprintf(string, "%d", asset->ampeg_bitrate);
414 append_acommand_line("-b");
415 append_acommand_line(string);
416 append_acommand_line("-");
417 append_acommand_line(asset->path);
419 audio_out = new FileMPEGAudio(this);
423 if(asset->ampeg_derivative == 3)
425 lame_global = lame_init();
426 lame_set_brate(lame_global, asset->ampeg_bitrate / 1000);
427 lame_set_quality(lame_global, 0);
428 lame_set_in_samplerate(lame_global,
430 if((result = lame_init_params(lame_global)) < 0)
432 printf(_("encode: lame_init_params returned %d\n"), result);
433 lame_close(lame_global);
437 if(!(lame_fd = fopen(asset->path, "w")))
439 perror("FileMPEG::open_file");
440 lame_close(lame_global);
446 printf("FileMPEG::open_file: ampeg_derivative=%d\n", asset->ampeg_derivative);
463 int FileMPEG::create_index()
465 // Calculate TOC path
466 char index_filename[BCTEXTLEN];
467 char source_filename[BCTEXTLEN];
468 IndexFile::get_index_filename(source_filename,
469 file->preferences->index_directory,
472 char *ptr = strrchr(index_filename, '.');
477 sprintf(ptr, ".toc");
479 // Test existence of TOC
480 FILE *test = fopen(index_filename, "r");
483 // Reopen with table of contents
488 // Create progress window.
489 // This gets around the fact that MWindowGUI is locked.
490 char progress_title[BCTEXTLEN];
491 char string[BCTEXTLEN];
492 sprintf(progress_title, "Creating %s\n", index_filename);
494 mpeg3_t *index_file = mpeg3_start_toc(asset->path, index_filename, &total_bytes);
495 struct timeval new_time;
496 struct timeval prev_time;
497 struct timeval start_time;
498 struct timeval current_time;
499 gettimeofday(&prev_time, 0);
500 gettimeofday(&start_time, 0);
502 BC_ProgressBox *progress = new BC_ProgressBox(-1,
510 int64_t bytes_processed;
511 mpeg3_do_toc(index_file, &bytes_processed);
512 gettimeofday(&new_time, 0);
514 if(new_time.tv_sec - prev_time.tv_sec >= 1)
516 gettimeofday(¤t_time, 0);
517 int64_t elapsed_seconds = current_time.tv_sec - start_time.tv_sec;
518 int64_t total_seconds = elapsed_seconds * total_bytes / bytes_processed;
519 int64_t eta = total_seconds - elapsed_seconds;
520 progress->update(bytes_processed, 1);
526 progress->update_title(string, 1);
527 // fprintf(stderr, "ETA: %dm%ds \r",
528 // bytes_processed * 100 / total_bytes,
532 prev_time = new_time;
534 if(bytes_processed >= total_bytes) break;
535 if(progress->is_cancelled())
542 mpeg3_stop_toc(index_file);
544 progress->stop_progress();
550 remove(index_filename);
554 // Fix date to date of source if success
562 // Reopen file from index path instead of asset path.
563 if(fd) mpeg3_close(fd);
564 if(!(fd = mpeg3_open(index_filename, &error)))
577 void FileMPEG::append_vcommand_line(const char *string)
581 char *argv = strdup(string);
582 vcommand_line.append(argv);
586 void FileMPEG::append_acommand_line(const char *string)
590 char *argv = strdup(string);
591 acommand_line.append(argv);
596 int FileMPEG::close_file()
599 next_frame_lock->unlock();
608 // End of sequence signal
609 if(file->asset->vmpeg_cmodel == MPEG_YUV422)
611 mpeg2enc_set_input_buffers(1, 0, 0, 0);
617 vcommand_line.remove_all_objects();
618 acommand_line.remove_all_objects();
622 toolame_send_buffer(0, 0);
628 lame_close(lame_global);
630 if(temp_frame) delete temp_frame;
631 if(toolame_temp) delete [] toolame_temp;
633 if(lame_temp[0]) delete [] lame_temp[0];
634 if(lame_temp[1]) delete [] lame_temp[1];
635 if(lame_output) delete [] lame_output;
636 if(lame_fd) fclose(lame_fd);
638 if(mjpeg_out) fclose(mjpeg_out);
641 FileBase::close_file();
645 int FileMPEG::get_best_colormodel(Asset *asset, int driver)
647 //printf("FileMPEG::get_best_colormodel 1\n");
652 if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
653 if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
655 case PLAYBACK_X11_XV:
656 if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
657 if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
659 case PLAYBACK_X11_GL:
666 case PLAYBACK_DV1394:
667 case PLAYBACK_FIREWIRE:
672 if(asset->vmpeg_cmodel == MPEG_YUV420) return BC_YUV420P;
673 if(asset->vmpeg_cmodel == MPEG_YUV422) return BC_YUV422P;
679 case CAPTURE_FIREWIRE:
680 case CAPTURE_IEC61883:
684 //printf("FileMPEG::get_best_colormodel 100\n");
687 int FileMPEG::colormodel_supported(int colormodel)
692 int FileMPEG::get_index(char *index_path)
697 // Convert the index tables from tracks to channels.
698 if(mpeg3_index_tracks(fd))
700 // Calculate size of buffer needed for all channels
702 for(int i = 0; i < mpeg3_index_tracks(fd); i++)
704 buffer_size += mpeg3_index_size(fd, i) *
705 mpeg3_index_channels(fd, i) *
709 asset->index_buffer = new float[buffer_size];
711 // Size of index buffer in floats
712 int current_offset = 0;
713 // Current asset channel
714 int current_channel = 0;
715 asset->index_zoom = mpeg3_index_zoom(fd);
716 asset->index_offsets = new int64_t[asset->channels];
717 asset->index_sizes = new int64_t[asset->channels];
718 for(int i = 0; i < mpeg3_index_tracks(fd); i++)
720 for(int j = 0; j < mpeg3_index_channels(fd, i); j++)
722 asset->index_offsets[current_channel] = current_offset;
723 asset->index_sizes[current_channel] = mpeg3_index_size(fd, i) * 2;
724 memcpy(asset->index_buffer + current_offset,
725 mpeg3_index_data(fd, i, j),
726 mpeg3_index_size(fd, i) * sizeof(float) * 2);
728 current_offset += mpeg3_index_size(fd, i) * 2;
734 asset->index_bytes = fs.get_size(asset->path);
736 asset->write_index(index_path, buffer_size * sizeof(float));
737 delete [] asset->index_buffer;
746 int FileMPEG::can_copy_from(Edit *edit, int64_t position)
752 int FileMPEG::set_audio_position(int64_t sample)
758 to_streamchannel(file->current_channel, stream, channel);
760 //printf("FileMPEG::set_audio_position %d %d %d\n", sample, mpeg3_get_sample(fd, stream), last_sample);
761 if(sample != mpeg3_get_sample(fd, stream) &&
762 sample != last_sample)
764 if(sample >= 0 && sample < asset->audio_length)
766 //printf("FileMPEG::set_audio_position seeking stream %d\n", sample);
767 return mpeg3_set_sample(fd, sample, stream);
776 int FileMPEG::set_video_position(int64_t x)
779 if(x >= 0 && x < asset->video_length)
781 //printf("FileMPEG::set_video_position 1 %lld\n", x);
782 mpeg3_set_frame(fd, x, file->current_layer);
788 int64_t FileMPEG::get_memory_usage()
792 int64_t result = mpeg3_memory_usage(fd);
799 int FileMPEG::write_samples(double **buffer, int64_t len)
803 //printf("FileMPEG::write_samples 1\n");
804 if(asset->ampeg_derivative == 2)
807 int channels = MIN(asset->channels, 2);
808 int64_t audio_size = len * channels * 2;
809 if(toolame_allocation < audio_size)
811 if(toolame_temp) delete [] toolame_temp;
812 toolame_temp = new unsigned char[audio_size];
813 toolame_allocation = audio_size;
816 for(int i = 0; i < channels; i++)
818 int16_t *output = ((int16_t*)toolame_temp) + i;
819 double *input = buffer[i];
820 for(int j = 0; j < len; j++)
822 int sample = (int)(*input * 0x7fff);
823 *output = (int16_t)(CLIP(sample, -0x8000, 0x7fff));
828 result = toolame_send_buffer((char*)toolame_temp, audio_size);
831 if(asset->ampeg_derivative == 3)
833 int channels = MIN(asset->channels, 2);
834 int64_t audio_size = len * channels;
835 if(!lame_global) return 1;
836 if(!lame_fd) return 1;
837 if(lame_allocation < audio_size)
839 if(lame_temp[0]) delete [] lame_temp[0];
840 if(lame_temp[1]) delete [] lame_temp[1];
841 lame_temp[0] = new float[audio_size];
842 lame_temp[1] = new float[audio_size];
843 lame_allocation = audio_size;
846 if(lame_output_allocation < audio_size * 4)
848 if(lame_output) delete [] lame_output;
849 lame_output_allocation = audio_size * 4;
850 lame_output = new char[lame_output_allocation];
853 for(int i = 0; i < channels; i++)
855 float *output = lame_temp[i];
856 double *input = buffer[i];
857 for(int j = 0; j < len; j++)
859 *output++ = *input++ * (float)32768;
863 result = lame_encode_buffer_float(lame_global,
865 (channels > 1) ? lame_temp[1] : lame_temp[0],
867 (unsigned char*)lame_output,
868 lame_output_allocation);
871 char *real_output = lame_output;
875 for(int i = 0; i < bytes; i++)
878 real_output = &lame_output[i];
884 if(bytes > 0 && lame_started)
886 result = !fwrite(real_output, 1, bytes, lame_fd);
888 perror("FileMPEG::write_samples");
900 int FileMPEG::write_frames(VFrame ***frames, int len)
906 int temp_w = (int)((asset->width + 15) / 16) * 16;
911 (asset->vmpeg_cmodel == MPEG_YUV420) ? BC_YUV420P : BC_YUV422P;
914 // Height depends on progressiveness
915 if(asset->vmpeg_progressive || asset->vmpeg_derivative == 1)
916 temp_h = (int)((asset->height + 15) / 16) * 16;
918 temp_h = (int)((asset->height + 31) / 32) * 32;
920 //printf("FileMPEG::write_frames 1\n");
922 // Only 1 layer is supported in MPEG output
923 for(int i = 0; i < 1; i++)
925 for(int j = 0; j < len && !result; j++)
927 VFrame *frame = frames[i][j];
931 if(asset->vmpeg_cmodel == MPEG_YUV422)
933 if(frame->get_w() == temp_w &&
934 frame->get_h() == temp_h &&
935 frame->get_color_model() == output_cmodel)
937 mpeg2enc_set_input_buffers(0,
938 (char*)frame->get_y(),
939 (char*)frame->get_u(),
940 (char*)frame->get_v());
945 (temp_frame->get_w() != temp_w ||
946 temp_frame->get_h() != temp_h ||
947 temp_frame->get_color_model() || output_cmodel))
956 temp_frame = new VFrame(0,
962 cmodel_transfer(temp_frame->get_rows(),
978 frame->get_color_model(),
979 temp_frame->get_color_model(),
984 mpeg2enc_set_input_buffers(0,
985 (char*)temp_frame->get_y(),
986 (char*)temp_frame->get_u(),
987 (char*)temp_frame->get_v());
992 // MJPEG uses the same dimensions as the input
993 if(frame->get_color_model() == output_cmodel)
995 mjpeg_y = frame->get_y();
996 mjpeg_u = frame->get_u();
997 mjpeg_v = frame->get_v();
1003 temp_frame = new VFrame(0,
1009 cmodel_transfer(temp_frame->get_rows(),
1011 temp_frame->get_y(),
1012 temp_frame->get_u(),
1013 temp_frame->get_v(),
1025 frame->get_color_model(),
1026 temp_frame->get_color_model(),
1031 mjpeg_y = temp_frame->get_y();
1032 mjpeg_u = temp_frame->get_u();
1033 mjpeg_v = temp_frame->get_v();
1039 next_frame_lock->unlock();
1040 next_frame_done->lock("FileMPEG::write_frames");
1041 if(mjpeg_error) result = 1;
1057 int FileMPEG::read_frame(VFrame *frame)
1063 // printf("FileMPEG::read_frame\n");
1064 // frame->dump_stacks();
1065 // frame->dump_params();
1067 if(mpeg3_colormodel(fd, 0) == MPEG3_YUV420P)
1068 src_cmodel = BC_YUV420P;
1070 if(mpeg3_colormodel(fd, 0) == MPEG3_YUV422P)
1071 src_cmodel = BC_YUV422P;
1073 switch(frame->get_color_model())
1077 case MPEG3_BGRA8888:
1079 case MPEG3_RGBA8888:
1080 case MPEG3_RGBA16161616:
1082 mpeg3_read_frame(fd,
1083 frame->get_rows(), /* Array of pointers to the start of each output row */
1084 0, /* Location in input frame to take picture */
1088 asset->width, /* Dimensions of output_rows */
1090 frame->get_color_model(), /* One of the color model #defines */
1091 file->current_layer);
1097 // Read these directly
1098 if(frame->get_color_model() == src_cmodel)
1101 mpeg3_read_yuvframe(fd,
1102 (char*)frame->get_y(),
1103 (char*)frame->get_u(),
1104 (char*)frame->get_v(),
1109 file->current_layer);
1113 // Process through temp frame
1117 mpeg3_read_yuvframe_ptr(fd,
1121 file->current_layer);
1125 cmodel_transfer(frame->get_rows(),
1142 frame->get_color_model(),
1156 void FileMPEG::to_streamchannel(int channel, int &stream_out, int &channel_out)
1158 for(stream_out = 0, channel_out = file->current_channel;
1159 stream_out < mpeg3_total_astreams(fd) &&
1160 channel_out >= mpeg3_audio_channels(fd, stream_out);
1161 channel_out -= mpeg3_audio_channels(fd, stream_out), stream_out++)
1165 int FileMPEG::read_samples(double *buffer, int64_t len)
1168 if(len < 0) return 0;
1170 // This is directed to a FileMPEGBuffer
1171 float *temp_float = new float[len];
1172 // Translate pure channel to a stream and a channel in the mpeg stream
1173 int stream, channel;
1174 to_streamchannel(file->current_channel, stream, channel);
1178 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
1180 mpeg3_set_sample(fd,
1181 file->current_sample,
1183 mpeg3_read_audio(fd,
1184 temp_float, /* Pointer to pre-allocated buffer of floats */
1185 0, /* Pointer to pre-allocated buffer of int16's */
1186 channel, /* Channel to decode */
1187 len, /* Number of samples to decode */
1188 stream); /* Stream containing the channel */
1191 // last_sample = file->current_sample;
1192 for(int i = 0; i < len; i++) buffer[i] = temp_float[i];
1194 delete [] temp_float;
1198 int FileMPEG::prefer_samples_float()
1203 int FileMPEG::read_samples_float(float *buffer, int64_t len)
1207 // Translate pure channel to a stream and a channel in the mpeg stream
1208 int stream, channel;
1209 to_streamchannel(file->current_channel, stream, channel);
1212 //printf("FileMPEG::read_samples 1 current_sample=%ld len=%ld channel=%d\n", file->current_sample, len, channel);
1214 mpeg3_set_sample(fd,
1215 file->current_sample,
1217 mpeg3_read_audio(fd,
1218 buffer, /* Pointer to pre-allocated buffer of floats */
1219 0, /* Pointer to pre-allocated buffer of int16's */
1220 channel, /* Channel to decode */
1221 len, /* Number of samples to decode */
1222 stream); /* Stream containing the channel */
1225 // last_sample = file->current_sample;
1227 //printf("FileMPEG::read_samples 100\n");
1233 char* FileMPEG::strtocompression(char *string)
1238 char* FileMPEG::compressiontostr(char *string)
1249 FileMPEGVideo::FileMPEGVideo(FileMPEG *file)
1255 if(file->asset->vmpeg_cmodel == MPEG_YUV422)
1257 mpeg2enc_init_buffers();
1258 mpeg2enc_set_w(file->asset->width);
1259 mpeg2enc_set_h(file->asset->height);
1260 mpeg2enc_set_rate(file->asset->frame_rate);
1264 FileMPEGVideo::~FileMPEGVideo()
1269 void FileMPEGVideo::run()
1271 if(file->asset->vmpeg_cmodel == MPEG_YUV422)
1273 printf("FileMPEGVideo::run ");
1274 for(int i = 0; i < file->vcommand_line.total; i++)
1275 printf("%s ", file->vcommand_line.values[i]);
1277 mpeg2enc(file->vcommand_line.total, file->vcommand_line.values);
1283 file->next_frame_lock->lock("FileMPEGVideo::run");
1286 file->next_frame_done->unlock();
1292 // YUV4 sequence header
1293 if(!file->wrote_header)
1295 file->wrote_header = 1;
1297 char string[BCTEXTLEN];
1298 char interlace_string[BCTEXTLEN];
1299 if(!file->asset->vmpeg_progressive)
1301 sprintf(interlace_string, file->asset->vmpeg_field_order ? "b" : "t");
1305 sprintf(interlace_string, "p");
1308 fprintf(file->mjpeg_out, "YUV4MPEG2 W%d H%d F%d:%d I%s A%d:%d C%s\n",
1310 file->asset->height,
1311 (int)(file->asset->frame_rate * 1001),
1314 (int)(file->asset->aspect_ratio * 1000),
1319 // YUV4 frame header
1320 fprintf(file->mjpeg_out, "FRAME\n");
1323 if(!fwrite(file->mjpeg_y, file->asset->width * file->asset->height, 1, file->mjpeg_out))
1324 file->mjpeg_error = 1;
1325 if(!fwrite(file->mjpeg_u, file->asset->width * file->asset->height / 4, 1, file->mjpeg_out))
1326 file->mjpeg_error = 1;
1327 if(!fwrite(file->mjpeg_v, file->asset->width * file->asset->height / 4, 1, file->mjpeg_out))
1328 file->mjpeg_error = 1;
1329 fflush(file->mjpeg_out);
1331 file->next_frame_done->unlock();
1333 pclose(file->mjpeg_out);
1334 file->mjpeg_out = 0;
1357 FileMPEGAudio::FileMPEGAudio(FileMPEG *file)
1361 toolame_init_buffers();
1364 FileMPEGAudio::~FileMPEGAudio()
1369 void FileMPEGAudio::run()
1371 file->toolame_result = toolame(file->acommand_line.total, file->acommand_line.values);
1381 MPEGConfigAudio::MPEGConfigAudio(BC_WindowBase *parent_window, Asset *asset)
1382 : BC_Window(PROGRAM_NAME ": Audio Compression",
1383 parent_window->get_abs_cursor_x(1),
1384 parent_window->get_abs_cursor_y(1),
1393 this->parent_window = parent_window;
1394 this->asset = asset;
1397 MPEGConfigAudio::~MPEGConfigAudio()
1401 int MPEGConfigAudio::create_objects()
1407 add_tool(new BC_Title(x, y, _("Layer:")));
1408 add_tool(layer = new MPEGLayer(x1, y, this));
1409 layer->create_objects();
1412 add_tool(new BC_Title(x, y, _("Kbits per second:")));
1413 add_tool(bitrate = new MPEGABitrate(x1, y, this));
1414 bitrate->create_objects();
1417 add_subwindow(new BC_OKButton(this));
1423 int MPEGConfigAudio::close_event()
1435 MPEGLayer::MPEGLayer(int x, int y, MPEGConfigAudio *gui)
1436 : BC_PopupMenu(x, y, 100, layer_to_string(gui->asset->ampeg_derivative))
1441 void MPEGLayer::create_objects()
1443 add_item(new BC_MenuItem(layer_to_string(2)));
1444 add_item(new BC_MenuItem(layer_to_string(3)));
1447 int MPEGLayer::handle_event()
1449 gui->asset->ampeg_derivative = string_to_layer(get_text());
1450 gui->bitrate->set_layer(gui->asset->ampeg_derivative);
1454 int MPEGLayer::string_to_layer(char *string)
1456 if(!strcasecmp(layer_to_string(2), string))
1458 if(!strcasecmp(layer_to_string(3), string))
1464 char* MPEGLayer::layer_to_string(int layer)
1488 MPEGABitrate::MPEGABitrate(int x, int y, MPEGConfigAudio *gui)
1492 bitrate_to_string(gui->string, gui->asset->ampeg_bitrate))
1497 void MPEGABitrate::create_objects()
1499 set_layer(gui->asset->ampeg_derivative);
1502 void MPEGABitrate::set_layer(int layer)
1504 while(total_items())
1511 add_item(new BC_MenuItem("160"));
1512 add_item(new BC_MenuItem("192"));
1513 add_item(new BC_MenuItem("224"));
1514 add_item(new BC_MenuItem("256"));
1515 add_item(new BC_MenuItem("320"));
1516 add_item(new BC_MenuItem("384"));
1520 add_item(new BC_MenuItem("8"));
1521 add_item(new BC_MenuItem("16"));
1522 add_item(new BC_MenuItem("24"));
1523 add_item(new BC_MenuItem("32"));
1524 add_item(new BC_MenuItem("40"));
1525 add_item(new BC_MenuItem("48"));
1526 add_item(new BC_MenuItem("56"));
1527 add_item(new BC_MenuItem("64"));
1528 add_item(new BC_MenuItem("80"));
1529 add_item(new BC_MenuItem("96"));
1530 add_item(new BC_MenuItem("112"));
1531 add_item(new BC_MenuItem("128"));
1532 add_item(new BC_MenuItem("144"));
1533 add_item(new BC_MenuItem("160"));
1534 add_item(new BC_MenuItem("192"));
1535 add_item(new BC_MenuItem("224"));
1536 add_item(new BC_MenuItem("256"));
1537 add_item(new BC_MenuItem("320"));
1541 int MPEGABitrate::handle_event()
1543 gui->asset->ampeg_bitrate = string_to_bitrate(get_text());
1547 int MPEGABitrate::string_to_bitrate(char *string)
1549 return atol(string);
1553 char* MPEGABitrate::bitrate_to_string(char *string, int bitrate)
1555 sprintf(string, "%d", bitrate);
1567 MPEGConfigVideo::MPEGConfigVideo(BC_WindowBase *parent_window,
1569 : BC_Window(PROGRAM_NAME ": Video Compression",
1570 parent_window->get_abs_cursor_x(1),
1571 parent_window->get_abs_cursor_y(1),
1580 this->parent_window = parent_window;
1581 this->asset = asset;
1585 MPEGConfigVideo::~MPEGConfigVideo()
1589 int MPEGConfigVideo::create_objects()
1596 add_subwindow(new BC_Title(x, y, _("Color model:")));
1597 add_subwindow(cmodel = new MPEGColorModel(x1, y, this));
1598 cmodel->create_objects();
1601 update_cmodel_objs();
1603 add_subwindow(new BC_OKButton(this));
1609 int MPEGConfigVideo::close_event()
1616 void MPEGConfigVideo::delete_cmodel_objs()
1621 delete fixed_bitrate;
1624 delete iframe_distance;
1625 delete pframe_distance;
1626 delete top_field_first;
1630 titles.remove_all_objects();
1634 void MPEGConfigVideo::reset_cmodel()
1642 iframe_distance = 0;
1643 pframe_distance = 0;
1644 top_field_first = 0;
1650 void MPEGConfigVideo::update_cmodel_objs()
1658 delete_cmodel_objs();
1660 if(asset->vmpeg_cmodel == MPEG_YUV420)
1662 add_subwindow(title = new BC_Title(x, y + 5, _("Format Preset:")));
1663 titles.append(title);
1664 add_subwindow(preset = new MPEGPreset(x1, y, this));
1665 preset->create_objects();
1669 add_subwindow(title = new BC_Title(x, y + 5, _("Derivative:")));
1670 titles.append(title);
1671 add_subwindow(derivative = new MPEGDerivative(x1, y, this));
1672 derivative->create_objects();
1675 add_subwindow(title = new BC_Title(x, y + 5, _("Bitrate:")));
1676 titles.append(title);
1677 add_subwindow(bitrate = new MPEGBitrate(x1, y, this));
1678 add_subwindow(fixed_bitrate = new MPEGFixedBitrate(x2, y, this));
1681 add_subwindow(title = new BC_Title(x, y, _("Quantization:")));
1682 titles.append(title);
1683 quant = new MPEGQuant(x1, y, this);
1684 quant->create_objects();
1685 add_subwindow(fixed_quant = new MPEGFixedQuant(x2, y, this));
1688 add_subwindow(title = new BC_Title(x, y, _("I frame distance:")));
1689 titles.append(title);
1690 iframe_distance = new MPEGIFrameDistance(x1, y, this);
1691 iframe_distance->create_objects();
1694 if(asset->vmpeg_cmodel == MPEG_YUV420)
1696 add_subwindow(title = new BC_Title(x, y, _("P frame distance:")));
1697 titles.append(title);
1698 pframe_distance = new MPEGPFrameDistance(x1, y, this);
1699 pframe_distance->create_objects();
1702 add_subwindow(top_field_first = new BC_CheckBox(x, y, &asset->vmpeg_field_order, _("Bottom field first")));
1706 add_subwindow(progressive = new BC_CheckBox(x, y, &asset->vmpeg_progressive, _("Progressive frames")));
1708 add_subwindow(denoise = new BC_CheckBox(x, y, &asset->vmpeg_denoise, _("Denoise")));
1710 add_subwindow(seq_codes = new BC_CheckBox(x, y, &asset->vmpeg_seq_codes, _("Sequence start codes in every GOP")));
1726 MPEGDerivative::MPEGDerivative(int x, int y, MPEGConfigVideo *gui)
1727 : BC_PopupMenu(x, y, 150, derivative_to_string(gui->asset->vmpeg_derivative))
1732 void MPEGDerivative::create_objects()
1734 add_item(new BC_MenuItem(derivative_to_string(1)));
1735 add_item(new BC_MenuItem(derivative_to_string(2)));
1738 int MPEGDerivative::handle_event()
1740 gui->asset->vmpeg_derivative = string_to_derivative(get_text());
1744 int MPEGDerivative::string_to_derivative(char *string)
1746 if(!strcasecmp(derivative_to_string(1), string))
1748 if(!strcasecmp(derivative_to_string(2), string))
1754 char* MPEGDerivative::derivative_to_string(int derivative)
1782 MPEGPreset::MPEGPreset(int x, int y, MPEGConfigVideo *gui)
1783 : BC_PopupMenu(x, y, 200, value_to_string(gui->asset->vmpeg_preset))
1788 void MPEGPreset::create_objects()
1790 for(int i = 0; i < 10; i++)
1792 add_item(new BC_MenuItem(value_to_string(i)));
1796 int MPEGPreset::handle_event()
1798 gui->asset->vmpeg_preset = string_to_value(get_text());
1802 int MPEGPreset::string_to_value(char *string)
1804 for(int i = 0; i < 10; i++)
1806 if(!strcasecmp(value_to_string(i), string))
1812 char* MPEGPreset::value_to_string(int derivative)
1816 case 0: return _("Generic MPEG-1"); break;
1817 case 1: return _("standard VCD"); break;
1818 case 2: return _("user VCD"); break;
1819 case 3: return _("Generic MPEG-2"); break;
1820 case 4: return _("standard SVCD"); break;
1821 case 5: return _("user SVCD"); break;
1822 case 6: return _("VCD Still sequence"); break;
1823 case 7: return _("SVCD Still sequence"); break;
1824 case 8: return _("DVD NAV"); break;
1825 case 9: return _("DVD"); break;
1826 default: return _("Generic MPEG-1"); break;
1840 MPEGBitrate::MPEGBitrate(int x, int y, MPEGConfigVideo *gui)
1841 : BC_TextBox(x, y, 100, 1, gui->asset->vmpeg_bitrate)
1847 int MPEGBitrate::handle_event()
1849 gui->asset->vmpeg_bitrate = atol(get_text());
1857 MPEGQuant::MPEGQuant(int x, int y, MPEGConfigVideo *gui)
1858 : BC_TumbleTextBox(gui,
1859 (int64_t)gui->asset->vmpeg_quantization,
1869 int MPEGQuant::handle_event()
1871 gui->asset->vmpeg_quantization = atol(get_text());
1875 MPEGFixedBitrate::MPEGFixedBitrate(int x, int y, MPEGConfigVideo *gui)
1876 : BC_Radial(x, y, gui->asset->vmpeg_fix_bitrate, _("Fixed bitrate"))
1881 int MPEGFixedBitrate::handle_event()
1884 gui->asset->vmpeg_fix_bitrate = 1;
1885 gui->fixed_quant->update(0);
1889 MPEGFixedQuant::MPEGFixedQuant(int x, int y, MPEGConfigVideo *gui)
1890 : BC_Radial(x, y, !gui->asset->vmpeg_fix_bitrate, _("Fixed quantization"))
1895 int MPEGFixedQuant::handle_event()
1898 gui->asset->vmpeg_fix_bitrate = 0;
1899 gui->fixed_bitrate->update(0);
1911 MPEGIFrameDistance::MPEGIFrameDistance(int x, int y, MPEGConfigVideo *gui)
1912 : BC_TumbleTextBox(gui,
1913 (int64_t)gui->asset->vmpeg_iframe_distance,
1923 int MPEGIFrameDistance::handle_event()
1925 gui->asset->vmpeg_iframe_distance = atoi(get_text());
1935 MPEGPFrameDistance::MPEGPFrameDistance(int x, int y, MPEGConfigVideo *gui)
1936 : BC_TumbleTextBox(gui,
1937 (int64_t)gui->asset->vmpeg_pframe_distance,
1947 int MPEGPFrameDistance::handle_event()
1949 gui->asset->vmpeg_pframe_distance = atoi(get_text());
1960 MPEGColorModel::MPEGColorModel(int x, int y, MPEGConfigVideo *gui)
1961 : BC_PopupMenu(x, y, 150, cmodel_to_string(gui->asset->vmpeg_cmodel))
1966 void MPEGColorModel::create_objects()
1968 add_item(new BC_MenuItem(cmodel_to_string(0)));
1969 add_item(new BC_MenuItem(cmodel_to_string(1)));
1972 int MPEGColorModel::handle_event()
1974 gui->asset->vmpeg_cmodel = string_to_cmodel(get_text());
1975 gui->update_cmodel_objs();
1979 int MPEGColorModel::string_to_cmodel(char *string)
1981 if(!strcasecmp(cmodel_to_string(0), string))
1983 if(!strcasecmp(cmodel_to_string(1), string))
1988 char* MPEGColorModel::cmodel_to_string(int cmodel)
1993 return _("YUV 4:2:0");
1997 return _("YUV 4:2:2");
2001 return _("YUV 4:2:0");