Improvements to exception handling, including using std::exception base class, and better general purpose exception handling in SWIG with Python. Also fixed an error when thowing exceptions inside OMP regions.

This commit is contained in:
Jonathan Thomas
2016-02-02 01:09:02 -06:00
parent 054175ddaa
commit 276aae35b3
6 changed files with 46 additions and 22 deletions
+1 -1
View File
@@ -39,7 +39,7 @@ namespace openshot {
* A custom error message field has been added to the std::exception base class. All * A custom error message field has been added to the std::exception base class. All
* OpenShot exception classes inherit from this class. * OpenShot exception classes inherit from this class.
*/ */
class BaseException //: public exception class BaseException : public std::exception //: public exception
{ {
protected: protected:
string m_message; string m_message;
+9 -8
View File
@@ -239,10 +239,10 @@ namespace openshot
void write_audio_packets(bool final); void write_audio_packets(bool final);
/// write video frame /// write video frame
void write_video_packet(tr1::shared_ptr<Frame> frame, AVFrame* frame_final); bool write_video_packet(tr1::shared_ptr<Frame> frame, AVFrame* frame_final);
/// write all queued frames /// write all queued frames
void write_queued_frames(); void write_queued_frames() throw (ErrorEncodingVideo);
public: public:
@@ -260,7 +260,7 @@ namespace openshot
bool IsOpen() { return is_open; }; bool IsOpen() { return is_open; };
/// Open writer /// 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) /// Output the ffmpeg info about this format, streams, and codecs (i.e. dump format)
void OutputStreamInfo(); void OutputStreamInfo();
@@ -284,7 +284,8 @@ namespace openshot
/// @param channels The number of audio channels needed in this file /// @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 channel_layout The 'layout' of audio channels (i.e. mono, stereo, surround, etc...)
/// @param bit_rate The audio bit rate used during encoding /// @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 /// @brief Set the cache size
/// @param new_size The number of frames to queue before writing to the file /// @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 interlaced Does this video need to be interlaced?
/// @param top_field_first Which frame should be used as the top field? /// @param top_field_first Which frame should be used as the top field?
/// @param bit_rate The video bit rate used during encoding /// @param bit_rate The video bit rate used during encoding
void SetVideoOptions(bool has_video, string codec, Fraction fps, int width, int height, 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)
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 /// @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. /// 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. /// @brief Add a frame to the stack waiting to be encoded.
/// @param frame The openshot::Frame object to write to this image /// @param frame The openshot::Frame object to write to this image
void WriteFrame(tr1::shared_ptr<Frame> frame) throw(WriterClosed); void WriteFrame(tr1::shared_ptr<Frame> frame) throw(ErrorEncodingVideo, WriterClosed);
/// @brief Write a block of frames from a reader /// @brief Write a block of frames from a reader
/// @param reader A openshot::ReaderBase object which will provide frames to be written /// @param reader A openshot::ReaderBase object which will provide frames to be written
/// @param start The starting frame number of the reader /// @param start The starting frame number of the reader
/// @param length The number of frames to write /// @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 /// @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. /// by the Close() method if this method has not yet been called.
+2 -2
View File
@@ -118,10 +118,10 @@ namespace openshot
virtual bool IsOpen() = 0; virtual bool IsOpen() = 0;
/// This method is required for all derived classes of WriterBase. Write a Frame to the video file. /// This method is required for all derived classes of WriterBase. Write a Frame to the video file.
virtual void WriteFrame(tr1::shared_ptr<Frame> frame) throw(WriterClosed) = 0; virtual void WriteFrame(tr1::shared_ptr<Frame> frame) throw(ErrorEncodingVideo, WriterClosed) = 0;
/// This method is required for all derived classes of WriterBase. Write a block of frames from a reader. /// 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 /// Get and Set JSON methods
string Json(); ///< Generate JSON string of this object string Json(); ///< Generate JSON string of this object
+23 -11
View File
@@ -32,7 +32,7 @@
using namespace openshot; 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), 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), 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), 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 // Open the writer
void FFmpegWriter::Open() throw(InvalidFile, InvalidCodec) void FFmpegWriter::Open() throw(InvalidFile, InvalidFormat, InvalidCodec, InvalidOptions, OutOfMemory, InvalidChannels, InvalidSampleRate)
{ {
// Open the writer // Open the writer
is_open = true; is_open = true;
@@ -111,8 +111,8 @@ void FFmpegWriter::initialize_streams()
} }
// Set video export options // Set video export options
void FFmpegWriter::SetVideoOptions(bool has_video, string codec, Fraction fps, int width, int height, 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)
Fraction pixel_ratio, bool interlaced, bool top_field_first, int bit_rate) throw(InvalidFile, InvalidFormat, InvalidCodec, InvalidOptions, OutOfMemory, InvalidChannels)
{ {
// Set the video options // Set the video options
if (codec.length() > 0) if (codec.length() > 0)
@@ -171,6 +171,7 @@ void FFmpegWriter::SetVideoOptions(bool has_video, string codec, Fraction fps, i
// Set audio export options // Set audio export options
void FFmpegWriter::SetAudioOptions(bool has_audio, string codec, int sample_rate, int channels, ChannelLayout channel_layout, int bit_rate) 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 // Set audio options
if (codec.length() > 0) if (codec.length() > 0)
@@ -342,7 +343,7 @@ void FFmpegWriter::WriteHeader()
} }
// Add a frame to the queue waiting to be encoded. // Add a frame to the queue waiting to be encoded.
void FFmpegWriter::WriteFrame(tr1::shared_ptr<Frame> frame) throw(WriterClosed) void FFmpegWriter::WriteFrame(tr1::shared_ptr<Frame> frame) throw(ErrorEncodingVideo, WriterClosed)
{ {
// Check for open reader (or throw exception) // Check for open reader (or throw exception)
if (!is_open) if (!is_open)
@@ -382,7 +383,7 @@ void FFmpegWriter::WriteFrame(tr1::shared_ptr<Frame> frame) throw(WriterClosed)
} }
// Write all frames in the queue to the video file. // 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); 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 // Allow nested OpenMP sections
omp_set_nested(true); omp_set_nested(true);
// Create blank exception
bool has_error_encoding_video = false;
#pragma omp parallel #pragma omp parallel
{ {
#pragma omp single #pragma omp single
@@ -449,7 +453,9 @@ void FFmpegWriter::write_queued_frames()
AVFrame *frame_final = av_frames[frame]; AVFrame *frame_final = av_frames[frame];
// Write frame to video file // 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 single
} // end omp parallel } // 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 // 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); 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> frame)
} }
// write video frame // write video frame
void FFmpegWriter::write_video_packet(tr1::shared_ptr<Frame> frame, AVFrame* frame_final) bool FFmpegWriter::write_video_packet(tr1::shared_ptr<Frame> 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); 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> frame, AVFrame* fra
if (error_code < 0) if (error_code < 0)
{ {
AppendDebugMethod("FFmpegWriter::write_video_packet ERROR [" + (string)av_err2str(error_code) + "]", "error_code", error_code, "", -1, "", -1, "", -1, "", -1, "", -1); 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 // Deallocate packet
@@ -1541,7 +1550,7 @@ void FFmpegWriter::write_video_packet(tr1::shared_ptr<Frame> frame, AVFrame* fra
if (error_code < 0) if (error_code < 0)
{ {
AppendDebugMethod("FFmpegWriter::write_video_packet ERROR [" + (string)av_err2str(error_code) + "]", "error_code", error_code, "", -1, "", -1, "", -1, "", -1, "", -1); 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> frame, AVFrame* fra
// Deallocate packet // Deallocate packet
av_free_packet(&pkt); av_free_packet(&pkt);
} }
// Success
return true;
} }
// Output the ffmpeg info about this format, streams, and codecs (i.e. dump format) // Output the ffmpeg info about this format, streams, and codecs (i.e. dump format)
+1
View File
@@ -40,6 +40,7 @@ IF (PYTHONLIBS_FOUND)
### Enable C++ support in SWIG ### Enable C++ support in SWIG
SET_SOURCE_FILES_PROPERTIES(openshot.i PROPERTIES CPLUSPLUS ON) SET_SOURCE_FILES_PROPERTIES(openshot.i PROPERTIES CPLUSPLUS ON)
SET(CMAKE_SWIG_FLAGS "")
### Add the SWIG interface file (which defines all the SWIG methods) ### Add the SWIG interface file (which defines all the SWIG methods)
SWIG_ADD_MODULE(openshot python openshot.i) SWIG_ADD_MODULE(openshot python openshot.i)
+10
View File
@@ -93,6 +93,16 @@
%} %}
#endif #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/Version.h"
%include "../../../include/ReaderBase.h" %include "../../../include/ReaderBase.h"