From fbc719b11fa0d68f3f89c9db51e8c5bebe7a93ab Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Mon, 24 Aug 2015 23:49:45 -0500 Subject: [PATCH] Many Windows related fixes and tweaks. Also fixed some issues with newer versions of CMake and Swig files. --- src/FFmpegReader.cpp | 35 ++++++++-------- src/FFmpegWriter.cpp | 14 +++++-- src/FrameMapper.cpp | 4 ++ src/Timeline.cpp | 5 +++ src/bindings/python/openshot.i | 4 +- src/bindings/ruby/openshot.i | 4 +- src/examples/Example.cpp | 74 +++++++++++++++++++--------------- 7 files changed, 84 insertions(+), 56 deletions(-) diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index 27b217c7..faeb450f 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -1218,25 +1218,12 @@ void FFmpegReader::Seek(long int requested_frame) throw(TooManySeeks) { // Seek to nearest key-frame (aka, i-frame) bool seek_worked = false; - - // Seek audio stream (if not already seeked... and if an audio stream is found) - int64_t seek_target = ConvertFrameToVideoPTS(requested_frame - buffer_amount); - if (!seek_worked && info.has_audio) - { - seek_target = ConvertFrameToAudioPTS(requested_frame - buffer_amount); - - if (info.has_audio && av_seek_frame(pFormatCtx, info.audio_stream_index, seek_target, AVSEEK_FLAG_BACKWARD) < 0) { - fprintf(stderr, "%s: error while seeking audio stream\n", pFormatCtx->filename); - } else - { - // AUDIO SEEK - is_video_seek = false; - seek_worked = true; - } - } + int64_t seek_target = 0; // Seek video stream (if any) - if (info.has_video) { + if (!seek_worked && info.has_video) + { + seek_target = ConvertFrameToVideoPTS(requested_frame - buffer_amount); if (av_seek_frame(pFormatCtx, info.video_stream_index, seek_target, AVSEEK_FLAG_BACKWARD) < 0) { fprintf(stderr, "%s: error while seeking video stream\n", pFormatCtx->filename); } else @@ -1247,6 +1234,20 @@ void FFmpegReader::Seek(long int requested_frame) throw(TooManySeeks) } } + // Seek audio stream (if not already seeked... and if an audio stream is found) + if (!seek_worked && info.has_audio) + { + seek_target = ConvertFrameToAudioPTS(requested_frame - buffer_amount); + if (info.has_audio && av_seek_frame(pFormatCtx, info.audio_stream_index, seek_target, AVSEEK_FLAG_BACKWARD) < 0) { + fprintf(stderr, "%s: error while seeking audio stream\n", pFormatCtx->filename); + } else + { + // AUDIO SEEK + is_video_seek = false; + seek_worked = true; + } + } + // Was the seek successful? if (seek_worked) { diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index d4402e95..02f0c9af 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -84,11 +84,11 @@ void FFmpegWriter::auto_detect_format() oc->oformat = fmt; // Update codec names - if (fmt->video_codec != AV_CODEC_ID_NONE) + if (fmt->video_codec != AV_CODEC_ID_NONE && info.has_video) // Update video codec name info.vcodec = avcodec_find_encoder(fmt->video_codec)->name; - if (fmt->audio_codec != AV_CODEC_ID_NONE) + if (fmt->audio_codec != AV_CODEC_ID_NONE && info.has_audio) // Update audio codec name info.acodec = avcodec_find_encoder(fmt->audio_codec)->name; } @@ -278,6 +278,10 @@ void FFmpegWriter::SetOption(StreamType stream, string name, string value) throw // Maximum bitrate convert >> c->rc_max_rate; + else if (name == "rc_buffer_size") + // Buffer size + convert >> c->rc_buffer_size; + else // Set AVOption #if LIBAVFORMAT_VERSION_MAJOR <= 53 @@ -879,10 +883,14 @@ AVStream* FFmpegWriter::add_video_stream() c->codec_type = CODEC_TYPE_VIDEO; #endif - /* put sample parameters */ + /* Init video encoder options */ c->bit_rate = info.video_bit_rate; c->rc_min_rate = info.video_bit_rate - (info.video_bit_rate / 6); c->rc_max_rate = info.video_bit_rate; + c->rc_buffer_size = FFMAX(c->rc_max_rate, 15000000) * 112L / 15000000 * 16384; + c->qmin = 2; + c->qmax = 30; + /* resolution must be a multiple of two */ // TODO: require /2 height and width c->width = info.width; diff --git a/src/FrameMapper.cpp b/src/FrameMapper.cpp index 8b0440ce..7512b78b 100644 --- a/src/FrameMapper.cpp +++ b/src/FrameMapper.cpp @@ -489,6 +489,10 @@ void FrameMapper::Open() throw(InvalidFile) // Open the reader reader->Open(); + + // Set child reader in debug mode (if needed) + if (debug) + reader->debug = true; } } diff --git a/src/Timeline.cpp b/src/Timeline.cpp index 81b85964..aa2fa118 100644 --- a/src/Timeline.cpp +++ b/src/Timeline.cpp @@ -492,6 +492,11 @@ void Timeline::update_open_clips(Clip *clip, bool does_clip_intersect) // Add clip to 'opened' list, because it's missing open_clips[clip] = clip; + // Set debug mode (if needed) + if (debug) + // Also set each Clip's reader to debug mode + clip->Reader()->debug = true; + // Open the clip clip->Open(); } diff --git a/src/bindings/python/openshot.i b/src/bindings/python/openshot.i index df815664..b12a0777 100644 --- a/src/bindings/python/openshot.i +++ b/src/bindings/python/openshot.i @@ -1,4 +1,4 @@ -####################### src/openshot.i (libopenshot) ######################## +/* ####################### src/openshot.i (libopenshot) ######################## # @brief SWIG configuration for libopenshot (to generate Python SWIG bindings) # @author Jonathan Thomas # @@ -22,7 +22,7 @@ # # You should have received a copy of the GNU Lesser General Public License # along with OpenShot Library. If not, see . -################################################################################ +################################################################################ */ %module openshot diff --git a/src/bindings/ruby/openshot.i b/src/bindings/ruby/openshot.i index c35dfbd0..52488d4f 100644 --- a/src/bindings/ruby/openshot.i +++ b/src/bindings/ruby/openshot.i @@ -1,4 +1,4 @@ -####################### src/openshot.i (libopenshot) ######################## +/* ####################### src/openshot.i (libopenshot) ######################## # @brief SWIG configuration for libopenshot (to generate Ruby SWIG bindings) # @author Jonathan Thomas # @@ -22,7 +22,7 @@ # # You should have received a copy of the GNU Lesser General Public License # along with OpenShot Library. If not, see . -################################################################################ +################################################################################ */ %module openshot diff --git a/src/examples/Example.cpp b/src/examples/Example.cpp index cfca63ed..ddd7d6c8 100644 --- a/src/examples/Example.cpp +++ b/src/examples/Example.cpp @@ -38,29 +38,41 @@ int main(int argc, char* argv[]) { // Create a reader - Clip clip_video("/home/jonathan/apps/libopenshot-git/src/examples/test.mp4"); + string path = "C:\\Users\\Jonathan\\Apps\\libopenshot\\src\\examples\\sintel_trailer-720p.mp4"; + cout << path << endl; + Clip clip_video("C:\\Users\\Jonathan\\Apps\\libopenshot\\src\\examples\\sintel_trailer-720p.mp4"); clip_video.Layer(0); clip_video.Position(0.0); - Clip clip_overlay("/home/jonathan/apps/libopenshot-git/src/examples/front3.png"); - clip_overlay.Layer(1); - //clip_overlay.Position(0.05); // Delay the overlay by 0.05 seconds - clip_overlay.End(0.5); // Make the duration of the overlay 1/2 second - +//// Clip clip_overlay("/home/jonathan/apps/libopenshot-git/src/examples/front3.png"); +//// clip_overlay.Layer(1); +//// //clip_overlay.Position(0.05); // Delay the overlay by 0.05 seconds +//// clip_overlay.End(0.5); // Make the duration of the overlay 1/2 second +// // Create a timeline - Timeline t(640, 480, Fraction(30, 1), 44100, 2, LAYOUT_STEREO); - - // Add clips - t.AddClip(&clip_video); - t.AddClip(&clip_overlay); + Timeline r9(640, 480, Fraction(30, 1), 44100, 2, LAYOUT_STEREO); + r9.debug = false; +// +// // Add clips + r9.AddClip(&clip_video); +// //t.AddClip(&clip_overlay); // Open Timeline - t.Open(); + r9.Open(); - t.GetFrame(2)->Display(); - - - return 0; +// cout << " --> 1" << endl; +// t.GetFrame(1); +// cout << " --> 500" << endl; +// t.GetFrame(500); +// cout << "1034" << endl; +// t.GetFrame(1034); +// cout << "1" << endl; +// t.GetFrame(1); +// cout << "1200" << endl; +// t.GetFrame(1200); +// +// +// return 0; // // FFmpegReader r110("/home/jonathan/Videos/PlaysTV/Team Fortress 2/2015_07_06_22_43_16-ses.mp4"); // r110.Open(); @@ -109,8 +121,6 @@ int main(int argc, char* argv[]) // t110.GetFrame(y); // } - return 0; - // FrameMapper m110(&r110, Fraction(24,1), PULLDOWN_NONE, 22050, 2, LAYOUT_STEREO); // m110.Open(); // @@ -164,9 +174,9 @@ int main(int argc, char* argv[]) // //t10.AddClip(&c20); // t10.Open(); - FFmpegReader r9("/home/jonathan/Videos/sintel_trailer-720p.mp4"); - r9.Open(); - r9.DisplayInfo(); +// FFmpegReader r9("/home/jonathan/Videos/sintel_trailer-720p.mp4"); +// r9.Open(); +// r9.DisplayInfo(); // Mapper @@ -176,16 +186,16 @@ int main(int argc, char* argv[]) //map.Open(); /* WRITER ---------------- */ - FFmpegWriter w9("/home/jonathan/output-pops.webm"); - w9.debug = false; + FFmpegWriter w9("C:\\Users\\Jonathan\\test-output.webm"); + w9.debug = true; //ImageWriter w9("/home/jonathan/output.gif"); // Set options - //w9.SetVideoOptions(true, "libx264", r9.info.fps, 1024, 576, Fraction(1,1), false, false, 1000000); + //w9.SetVideoOptions(true, "mpeg4", r9.info.fps, r9.info.width, r9.info.height, Fraction(1,1), false, false, 1000000); //w9.SetAudioOptions(true, "mp2", r9.info.sample_rate, r9.info.channels, r9.info.channel_layout, 64000); w9.SetAudioOptions(true, "libvorbis", r9.info.sample_rate, r9.info.channels, r9.info.channel_layout, 128000); - w9.SetVideoOptions(true, "libvpx", r9.info.fps, 1024, 576, Fraction(1,1), false, false, 3000000); - //w9.SetAudioOptions(true, "libmp3lame", 22050, t10.info.channels, t10.info.channel_layout, 120000); + w9.SetVideoOptions(true, "libvpx", r9.info.fps, r9.info.width, r9.info.height, Fraction(1,1), false, false, 3000000); + //w9.SetAudioOptions(true, "libmp3lame", 22050, r9.info.channels, r9.info.channel_layout, 120000); //w9.SetVideoOptions(true, "libx264", t10.info.fps, t10.info.width, t10.info.height, t10.info.pixel_ratio, false, false, 1500000); //w9.SetVideoOptions(true, "rawvideo", r9.info.fps, 400, 2, r9.info.pixel_ratio, false, false, 20000000); //w9.SetVideoOptions("GIF", r9.info.fps, r9.info.width, r9.info.height, 70, 1, true); @@ -194,23 +204,23 @@ int main(int argc, char* argv[]) w9.Open(); // Prepare Streams - //w9.PrepareStreams(); + w9.PrepareStreams(); // w9.SetOption(VIDEO_STREAM, "qmin", "2" ); // w9.SetOption(VIDEO_STREAM, "qmax", "30" ); -// w9.SetOption(VIDEO_STREAM, "crf", "10" ); + w9.SetOption(VIDEO_STREAM, "crf", "10" ); // w9.SetOption(VIDEO_STREAM, "rc_min_rate", "2000000" ); // w9.SetOption(VIDEO_STREAM, "rc_max_rate", "4000000" ); // w9.SetOption(VIDEO_STREAM, "max_b_frames", "10" ); // Write header - //w9.WriteHeader(); + w9.WriteHeader(); //r9.DisplayInfo(); // 147000 frames, 28100 frames //for (int frame = 1; frame <= (r9.info.video_length - 1); frame++) //for (int z = 0; z < 2; z++) - for (long int frame = 1; frame <= 700; frame++) + for (long int frame = 500; frame <= 750; frame++) //int frame = 1; //while (true) { @@ -219,8 +229,8 @@ int main(int argc, char* argv[]) cout << "get " << frame << " (frame: " << frame_number << ") " << endl; tr1::shared_ptr f = r9.GetFrame(frame_number); - cout << "mapped frame channel layouts: " << f->ChannelsLayout() << endl; - cout << "display it (" << f->number << ", " << f << ")" << endl; + //cout << "mapped frame channel layouts: " << f->ChannelsLayout() << endl; + //cout << "display it (" << f->number << ", " << f << ")" << endl; //r9.GetFrame(frame_number)->DisplayWaveform(); //if (frame >= 495) // f->DisplayWaveform();