diff --git a/include/FFmpegReader.h b/include/FFmpegReader.h index 405f1d28..6aaf49b2 100644 --- a/include/FFmpegReader.h +++ b/include/FFmpegReader.h @@ -236,7 +236,7 @@ namespace openshot /// /// @returns The requested frame of video /// @param requested_frame The frame number that is requested. - tr1::shared_ptr GetFrame(int requested_frame) throw(ReaderClosed, TooManySeeks); + tr1::shared_ptr GetFrame(int requested_frame) throw(OutOfBoundsFrame, ReaderClosed, TooManySeeks); /// Determine if reader is open or closed bool IsOpen() { return is_open; }; diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index 646ee1b8..1ac88dd0 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -378,7 +378,7 @@ void FFmpegReader::UpdateVideoInfo() } -tr1::shared_ptr FFmpegReader::GetFrame(int requested_frame) throw(ReaderClosed, TooManySeeks) +tr1::shared_ptr FFmpegReader::GetFrame(int requested_frame) throw(OutOfBoundsFrame, ReaderClosed, TooManySeeks) { if (display_debug) cout << "GET FRAME " << requested_frame << ", last_frame: " << last_frame << endl; @@ -477,6 +477,11 @@ tr1::shared_ptr FFmpegReader::ReadStream(int requested_frame) { // Break loop when no more packets found end_of_stream = true; + + // Wait for all frames to be processed + while (processing_video_frames.size() + processing_audio_frames.size() == 0) + Sleep(1); + break; } @@ -556,17 +561,23 @@ tr1::shared_ptr FFmpegReader::ReadStream(int requested_frame) } // end omp parallel - // End of stream? Mark the any other working frames as 'finished' - if (end_of_stream) + // End of stream? + if (end_of_stream) { + // Mark the any other working frames as 'finished' CheckWorkingFrames(end_of_stream); + // Update readers video length (to a guess of the correct video length) + info.video_length = requested_frame - 1; // just a guess, but this frame is certainly out of bounds + } + // Return requested frame (if found) if (final_cache.Exists(requested_frame)) // Return prepared frame return final_cache.GetFrame(requested_frame); else - // Return blank frame - return CreateFrame(requested_frame); + // Frame not found (possibily end of stream) + throw OutOfBoundsFrame("Frame not found in video (invalid frame requested)", requested_frame, info.video_length); + } // Get the next packet (if any) diff --git a/src/Main.cpp b/src/Main.cpp index 7dd948d6..cee22e4b 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -40,6 +40,15 @@ using namespace tr1; int main(int argc, char* argv[]) { + FFmpegReader r99("/home/jonathan/Videos/sintel_trailer-720p.mp4"); + r99.Open(); + for (int count99 = 1; count99 < 10000000; count99++) { + cout << count99 << endl; + r99.GetFrame(count99); + } + + return 0; + Profile p("/home/jonathan/Apps/openshot/openshot/profiles/atsc_1080p_25"); return 0; diff --git a/src/Qt/AudioPlaybackThread.cpp b/src/Qt/AudioPlaybackThread.cpp index 49282afd..12891230 100644 --- a/src/Qt/AudioPlaybackThread.cpp +++ b/src/Qt/AudioPlaybackThread.cpp @@ -63,12 +63,17 @@ namespace openshot { while (!threadShouldExit()) { play.wait(); +/* + // Create TimeSliceThread for audio buffering + TimeSliceThread my_thread("Audio buffer thread"); + + // Start thread + my_thread.startThread(); - /* transport.setSource( &source, 5000, // tells it to buffer this many samples ahead - nullptr, + &my_thread, sampleRate, numChannels); transport.setPosition(0); @@ -79,7 +84,7 @@ namespace openshot } transport.stop(); transport.setSource(0); - */ +*/ played.signal(); } diff --git a/src/RendererBase.cpp b/src/RendererBase.cpp index 7125ddab..32935506 100644 --- a/src/RendererBase.cpp +++ b/src/RendererBase.cpp @@ -49,17 +49,18 @@ void RendererBase::paint(const std::tr1::shared_ptr & frame) /// Use realloc for fast memory allocation. /// TODO: consider locking the buffer for mt safety buffer = reinterpret_cast(realloc(buffer, bufferSize)); -#if false - /** - * FIXME: this is buggy somehow... - */ - image->readPixels(Magick::RGBQuantum, buffer); +#if true + // Not sure if this is actually faster... but it works now + image->getPixels(0,0, width, height); // load pixels into cache + image->depth( 8 ); // this is required of it crashes + image->writePixels(Magick::RGBQuantum, buffer); // write pixel data to our buffer #else + // Iterate through the pixel packets, and load our own buffer const Magick::PixelPacket *pixels = frame->GetPixels(); for (int n = 0, i = 0; n < width * height; n += 1, i += 3) { - buffer[i+0] = pixels[n].red >> 8; - buffer[i+1] = pixels[n].green >> 8; - buffer[i+2] = pixels[n].blue >> 8; + buffer[i+0] = pixels[n].red >> 8; + buffer[i+1] = pixels[n].green >> 8; + buffer[i+2] = pixels[n].blue >> 8; } #endif this->render(RGB_888, width, height, width * BPP, buffer);