diff --git a/include/Exceptions.h b/include/Exceptions.h
index 82f627e8..1f879388 100644
--- a/include/Exceptions.h
+++ b/include/Exceptions.h
@@ -39,7 +39,7 @@ namespace openshot {
* A custom error message field has been added to the std::exception base class. All
* OpenShot exception classes inherit from this class.
*/
- class BaseException //: public exception
+ class BaseException : public std::exception //: public exception
{
protected:
string m_message;
diff --git a/include/FFmpegWriter.h b/include/FFmpegWriter.h
index 0b9b33f9..f1481b70 100644
--- a/include/FFmpegWriter.h
+++ b/include/FFmpegWriter.h
@@ -239,10 +239,10 @@ namespace openshot
void write_audio_packets(bool final);
/// write video frame
- void write_video_packet(tr1::shared_ptr frame, AVFrame* frame_final);
+ bool write_video_packet(tr1::shared_ptr frame, AVFrame* frame_final);
/// write all queued frames
- void write_queued_frames();
+ void write_queued_frames() throw (ErrorEncodingVideo);
public:
@@ -260,7 +260,7 @@ namespace openshot
bool IsOpen() { return is_open; };
/// Open writer
- void Open() throw(InvalidFile, InvalidCodec);
+ void Open() throw(InvalidFile, InvalidFormat, InvalidCodec, InvalidOptions, OutOfMemory, InvalidChannels, InvalidSampleRate);
/// Output the ffmpeg info about this format, streams, and codecs (i.e. dump format)
void OutputStreamInfo();
@@ -284,7 +284,8 @@ namespace openshot
/// @param channels The number of audio channels needed in this file
/// @param channel_layout The 'layout' of audio channels (i.e. mono, stereo, surround, etc...)
/// @param bit_rate The audio bit rate used during encoding
- void SetAudioOptions(bool has_audio, string codec, int sample_rate, int channels, ChannelLayout channel_layout, int bit_rate);
+ void SetAudioOptions(bool has_audio, string codec, int sample_rate, int channels, ChannelLayout channel_layout, int bit_rate)
+ throw(InvalidFile, InvalidFormat, InvalidCodec, InvalidOptions, OutOfMemory, InvalidChannels);
/// @brief Set the cache size
/// @param new_size The number of frames to queue before writing to the file
@@ -300,8 +301,8 @@ namespace openshot
/// @param interlaced Does this video need to be interlaced?
/// @param top_field_first Which frame should be used as the top field?
/// @param bit_rate The video bit rate used during encoding
- void SetVideoOptions(bool has_video, string codec, Fraction fps, int width, int height,
- Fraction pixel_ratio, bool interlaced, bool top_field_first, int bit_rate);
+ void SetVideoOptions(bool has_video, string codec, Fraction fps, int width, int height,Fraction pixel_ratio, bool interlaced, bool top_field_first, int bit_rate)
+ throw(InvalidFile, InvalidFormat, InvalidCodec, InvalidOptions, OutOfMemory, InvalidChannels);
/// @brief Set custom options (some codecs accept additional params). This must be called after the
/// PrepareStreams() method, otherwise the streams have not been initialized yet.
@@ -316,13 +317,13 @@ namespace openshot
/// @brief Add a frame to the stack waiting to be encoded.
/// @param frame The openshot::Frame object to write to this image
- void WriteFrame(tr1::shared_ptr frame) throw(WriterClosed);
+ void WriteFrame(tr1::shared_ptr frame) throw(ErrorEncodingVideo, WriterClosed);
/// @brief Write a block of frames from a reader
/// @param reader A openshot::ReaderBase object which will provide frames to be written
/// @param start The starting frame number of the reader
/// @param length The number of frames to write
- void WriteFrame(ReaderBase* reader, long int start, long int length) throw(WriterClosed);
+ void WriteFrame(ReaderBase* reader, long int start, long int length) throw(ErrorEncodingVideo, WriterClosed);
/// @brief Write the file trailer (after all frames are written). This is called automatically
/// by the Close() method if this method has not yet been called.
diff --git a/include/WriterBase.h b/include/WriterBase.h
index 8516158e..44ffe0f5 100644
--- a/include/WriterBase.h
+++ b/include/WriterBase.h
@@ -118,10 +118,10 @@ namespace openshot
virtual bool IsOpen() = 0;
/// This method is required for all derived classes of WriterBase. Write a Frame to the video file.
- virtual void WriteFrame(tr1::shared_ptr frame) throw(WriterClosed) = 0;
+ virtual void WriteFrame(tr1::shared_ptr frame) throw(ErrorEncodingVideo, WriterClosed) = 0;
/// This method is required for all derived classes of WriterBase. Write a block of frames from a reader.
- virtual void WriteFrame(ReaderBase* reader, long int start, long int length) throw(WriterClosed) = 0;
+ virtual void WriteFrame(ReaderBase* reader, long int start, long int length) throw(ErrorEncodingVideo, WriterClosed) = 0;
/// Get and Set JSON methods
string Json(); ///< Generate JSON string of this object
diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp
index c9a6eca7..33745e64 100644
--- a/src/FFmpegWriter.cpp
+++ b/src/FFmpegWriter.cpp
@@ -32,7 +32,7 @@
using namespace openshot;
-FFmpegWriter::FFmpegWriter(string path) throw (InvalidFile, InvalidFormat, InvalidCodec, InvalidOptions, OutOfMemory) :
+FFmpegWriter::FFmpegWriter(string path) throw (InvalidFile, InvalidFormat, InvalidCodec, InvalidOptions, OutOfMemory):
path(path), fmt(NULL), oc(NULL), audio_st(NULL), video_st(NULL), audio_pts(0), video_pts(0), samples(NULL),
audio_outbuf(NULL), audio_outbuf_size(0), audio_input_frame_size(0), audio_input_position(0),
initial_audio_input_frame_size(0), img_convert_ctx(NULL), cache_size(8), num_of_rescalers(32),
@@ -53,7 +53,7 @@ FFmpegWriter::FFmpegWriter(string path) throw (InvalidFile, InvalidFormat, Inval
}
// Open the writer
-void FFmpegWriter::Open() throw(InvalidFile, InvalidCodec)
+void FFmpegWriter::Open() throw(InvalidFile, InvalidFormat, InvalidCodec, InvalidOptions, OutOfMemory, InvalidChannels, InvalidSampleRate)
{
// Open the writer
is_open = true;
@@ -111,8 +111,8 @@ void FFmpegWriter::initialize_streams()
}
// Set video export options
-void FFmpegWriter::SetVideoOptions(bool has_video, string codec, Fraction fps, int width, int height,
- Fraction pixel_ratio, bool interlaced, bool top_field_first, int bit_rate)
+void FFmpegWriter::SetVideoOptions(bool has_video, string codec, Fraction fps, int width, int height, Fraction pixel_ratio, bool interlaced, bool top_field_first, int bit_rate)
+ throw(InvalidFile, InvalidFormat, InvalidCodec, InvalidOptions, OutOfMemory, InvalidChannels)
{
// Set the video options
if (codec.length() > 0)
@@ -171,6 +171,7 @@ void FFmpegWriter::SetVideoOptions(bool has_video, string codec, Fraction fps, i
// Set audio export options
void FFmpegWriter::SetAudioOptions(bool has_audio, string codec, int sample_rate, int channels, ChannelLayout channel_layout, int bit_rate)
+ throw(InvalidFile, InvalidFormat, InvalidCodec, InvalidOptions, OutOfMemory, InvalidChannels)
{
// Set audio options
if (codec.length() > 0)
@@ -342,7 +343,7 @@ void FFmpegWriter::WriteHeader()
}
// Add a frame to the queue waiting to be encoded.
-void FFmpegWriter::WriteFrame(tr1::shared_ptr frame) throw(WriterClosed)
+void FFmpegWriter::WriteFrame(tr1::shared_ptr frame) throw(ErrorEncodingVideo, WriterClosed)
{
// Check for open reader (or throw exception)
if (!is_open)
@@ -382,7 +383,7 @@ void FFmpegWriter::WriteFrame(tr1::shared_ptr frame) throw(WriterClosed)
}
// Write all frames in the queue to the video file.
-void FFmpegWriter::write_queued_frames()
+void FFmpegWriter::write_queued_frames() throw (ErrorEncodingVideo)
{
AppendDebugMethod("FFmpegWriter::write_queued_frames", "spooled_video_frames.size()", spooled_video_frames.size(), "spooled_audio_frames.size()", spooled_audio_frames.size(), "", -1, "", -1, "", -1, "", -1);
@@ -402,6 +403,9 @@ void FFmpegWriter::write_queued_frames()
// Allow nested OpenMP sections
omp_set_nested(true);
+ // Create blank exception
+ bool has_error_encoding_video = false;
+
#pragma omp parallel
{
#pragma omp single
@@ -449,7 +453,9 @@ void FFmpegWriter::write_queued_frames()
AVFrame *frame_final = av_frames[frame];
// Write frame to video file
- write_video_packet(frame, frame_final);
+ bool success = write_video_packet(frame, frame_final);
+ if (!success)
+ has_error_encoding_video = true;
}
}
@@ -485,10 +491,13 @@ void FFmpegWriter::write_queued_frames()
} // end omp single
} // end omp parallel
+ // Raise exception from main thread
+ if (has_error_encoding_video)
+ throw ErrorEncodingVideo("Error while writing raw video frame", -1);
}
// Write a block of frames from a reader
-void FFmpegWriter::WriteFrame(ReaderBase* reader, long int start, long int length) throw(WriterClosed)
+void FFmpegWriter::WriteFrame(ReaderBase* reader, long int start, long int length) throw(ErrorEncodingVideo, WriterClosed)
{
AppendDebugMethod("FFmpegWriter::WriteFrame (from Reader)", "start", start, "length", length, "", -1, "", -1, "", -1, "", -1);
@@ -1445,7 +1454,7 @@ void FFmpegWriter::process_video_packet(tr1::shared_ptr frame)
}
// write video frame
-void FFmpegWriter::write_video_packet(tr1::shared_ptr frame, AVFrame* frame_final)
+bool FFmpegWriter::write_video_packet(tr1::shared_ptr frame, AVFrame* frame_final)
{
AppendDebugMethod("FFmpegWriter::write_video_packet", "frame->number", frame->number, "oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE, "", -1, "", -1, "", -1, "", -1);
@@ -1468,7 +1477,7 @@ void FFmpegWriter::write_video_packet(tr1::shared_ptr frame, AVFrame* fra
if (error_code < 0)
{
AppendDebugMethod("FFmpegWriter::write_video_packet ERROR [" + (string)av_err2str(error_code) + "]", "error_code", error_code, "", -1, "", -1, "", -1, "", -1, "", -1);
- throw ErrorEncodingVideo("Error while writing raw video frame", frame->number);
+ return false;
}
// Deallocate packet
@@ -1541,7 +1550,7 @@ void FFmpegWriter::write_video_packet(tr1::shared_ptr frame, AVFrame* fra
if (error_code < 0)
{
AppendDebugMethod("FFmpegWriter::write_video_packet ERROR [" + (string)av_err2str(error_code) + "]", "error_code", error_code, "", -1, "", -1, "", -1, "", -1, "", -1);
- throw ErrorEncodingVideo("Error while writing compressed video frame", frame->number);
+ return false;
}
}
@@ -1552,6 +1561,9 @@ void FFmpegWriter::write_video_packet(tr1::shared_ptr frame, AVFrame* fra
// Deallocate packet
av_free_packet(&pkt);
}
+
+ // Success
+ return true;
}
// Output the ffmpeg info about this format, streams, and codecs (i.e. dump format)
diff --git a/src/bindings/python/CMakeLists.txt b/src/bindings/python/CMakeLists.txt
index 34f1a432..4f83b2e7 100644
--- a/src/bindings/python/CMakeLists.txt
+++ b/src/bindings/python/CMakeLists.txt
@@ -40,6 +40,7 @@ IF (PYTHONLIBS_FOUND)
### Enable C++ support in SWIG
SET_SOURCE_FILES_PROPERTIES(openshot.i PROPERTIES CPLUSPLUS ON)
+ SET(CMAKE_SWIG_FLAGS "")
### Add the SWIG interface file (which defines all the SWIG methods)
SWIG_ADD_MODULE(openshot python openshot.i)
diff --git a/src/bindings/python/openshot.i b/src/bindings/python/openshot.i
index b5e0dd76..e755c004 100644
--- a/src/bindings/python/openshot.i
+++ b/src/bindings/python/openshot.i
@@ -93,6 +93,16 @@
%}
#endif
+/* Generic language independent exception handler. */
+%include "exception.i"
+%exception {
+ try {
+ $action
+ }
+ catch (std::exception &e) {
+ SWIG_exception_fail(SWIG_RuntimeError, e.what());
+ }
+}
%include "../../../include/Version.h"
%include "../../../include/ReaderBase.h"