]> git.sesse.net Git - casparcg/blob - modules/ffmpeg/ffmpeg_error.h
2.0.2: Is now locked, only bug fixes should be added. New features go into 2.1.0.
[casparcg] / modules / ffmpeg / ffmpeg_error.h
1 /*\r
2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>\r
3 *\r
4 * This file is part of CasparCG (www.casparcg.com).\r
5 *\r
6 * CasparCG is free software: you can redistribute it and/or modify\r
7 * it under the terms of the GNU General Public License as published by\r
8 * the Free Software Foundation, either version 3 of the License, or\r
9 * (at your option) any later version.\r
10 *\r
11 * CasparCG is distributed in the hope that it will be useful,\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14 * GNU General Public License for more details.\r
15 *\r
16 * You should have received a copy of the GNU General Public License\r
17 * along with CasparCG. If not, see <http://www.gnu.org/licenses/>.\r
18 *\r
19 * Author: Robert Nagy, ronag89@gmail.com\r
20 */\r
21 \r
22 #pragma once\r
23 \r
24 #include <common/exception/exceptions.h>\r
25 #include <common/utility/string.h>\r
26 \r
27 #include <string>\r
28 \r
29 #pragma warning(push, 1)\r
30 \r
31 extern "C" \r
32 {\r
33 #include <libavutil/error.h>\r
34 }\r
35 \r
36 #pragma warning(pop)\r
37 \r
38 namespace caspar { namespace ffmpeg {\r
39 \r
40 struct ffmpeg_error : virtual caspar_exception{};\r
41 struct averror_bsf_not_found : virtual ffmpeg_error{};\r
42 struct averror_decoder_not_found : virtual ffmpeg_error{};\r
43 struct averror_demuxer_not_found : virtual ffmpeg_error{};\r
44 struct averror_encoder_not_found : virtual ffmpeg_error{};\r
45 struct averror_eof : virtual ffmpeg_error{};\r
46 struct averror_exit : virtual ffmpeg_error{};\r
47 struct averror_filter_not_found : virtual ffmpeg_error{};\r
48 struct averror_muxer_not_found : virtual ffmpeg_error{};\r
49 struct averror_option_not_found : virtual ffmpeg_error{};\r
50 struct averror_patchwelcome : virtual ffmpeg_error{};\r
51 struct averror_protocol_not_found : virtual ffmpeg_error{};\r
52 struct averror_stream_not_found : virtual ffmpeg_error{};\r
53 \r
54 static std::string av_error_str(int errn)\r
55 {\r
56         char buf[256];\r
57         memset(buf, 0, 256);\r
58         if(av_strerror(errn, buf, 256) < 0)\r
59                 return "";\r
60         return std::string(buf);\r
61 }\r
62 \r
63 static void throw_on_ffmpeg_error(int ret, const char* source, const char* func, const char* local_func, const char* file, int line)\r
64 {\r
65         if(ret >= 0)\r
66                 return;\r
67 \r
68         switch(ret)\r
69         {\r
70         case AVERROR_BSF_NOT_FOUND:\r
71                 ::boost::exception_detail::throw_exception_(averror_bsf_not_found()<<                                                                           \r
72                         msg_info(av_error_str(ret)) <<                                                  \r
73                         source_info(narrow(source)) <<                                          \r
74                         boost::errinfo_api_function(func) <<                                    \r
75                         boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line);  \r
76         case AVERROR_DECODER_NOT_FOUND:\r
77                 ::boost::exception_detail::throw_exception_(averror_decoder_not_found()<<                                                                               \r
78                         msg_info(av_error_str(ret)) <<                                                  \r
79                         source_info(narrow(source)) <<                                          \r
80                         boost::errinfo_api_function(func) <<                                    \r
81                         boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line);\r
82         case AVERROR_DEMUXER_NOT_FOUND:\r
83                 ::boost::exception_detail::throw_exception_(averror_demuxer_not_found()<<                                                                               \r
84                         msg_info(av_error_str(ret)) <<                                                  \r
85                         source_info(narrow(source)) <<                                          \r
86                         boost::errinfo_api_function(func) <<                                    \r
87                         boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line);\r
88         case AVERROR_ENCODER_NOT_FOUND:\r
89                 ::boost::exception_detail::throw_exception_(averror_encoder_not_found()<<                                                                               \r
90                         msg_info(av_error_str(ret)) <<                                                  \r
91                         source_info(narrow(source)) <<                                          \r
92                         boost::errinfo_api_function(func) <<                                    \r
93                         boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line);  \r
94         case AVERROR_EOF:       \r
95                 ::boost::exception_detail::throw_exception_(averror_eof()<<                                                                             \r
96                         msg_info(av_error_str(ret)) <<                                                  \r
97                         source_info(narrow(source)) <<                                          \r
98                         boost::errinfo_api_function(func) <<                                    \r
99                         boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line);\r
100         case AVERROR_EXIT:                              \r
101                 ::boost::exception_detail::throw_exception_(averror_exit()<<                                                                            \r
102                         msg_info(av_error_str(ret)) <<                                                  \r
103                         source_info(narrow(source)) <<                                          \r
104                         boost::errinfo_api_function(func) <<                                    \r
105                         boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line);\r
106         case AVERROR_FILTER_NOT_FOUND:                          \r
107                 ::boost::exception_detail::throw_exception_(averror_filter_not_found()<<                                                                                \r
108                         msg_info(av_error_str(ret)) <<                                                  \r
109                         source_info(narrow(source)) <<                                          \r
110                         boost::errinfo_api_function(func) <<                                    \r
111                         boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line);\r
112         case AVERROR_MUXER_NOT_FOUND:   \r
113                 ::boost::exception_detail::throw_exception_(averror_muxer_not_found()<<                                                                         \r
114                         msg_info(av_error_str(ret)) <<                                                  \r
115                         source_info(narrow(source)) <<                                          \r
116                         boost::errinfo_api_function(func) <<                                    \r
117                         boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line);\r
118         case AVERROR_OPTION_NOT_FOUND:  \r
119                 ::boost::exception_detail::throw_exception_(averror_option_not_found()<<                                                                                \r
120                         msg_info(av_error_str(ret)) <<                                                  \r
121                         source_info(narrow(source)) <<                                          \r
122                         boost::errinfo_api_function(func) <<                                    \r
123                         boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line);\r
124         case AVERROR_PATCHWELCOME:      \r
125                 ::boost::exception_detail::throw_exception_(averror_patchwelcome()<<                                                                            \r
126                         msg_info(av_error_str(ret)) <<                                                  \r
127                         source_info(narrow(source)) <<                                          \r
128                         boost::errinfo_api_function(func) <<                                    \r
129                         boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line);\r
130         case AVERROR_PROTOCOL_NOT_FOUND:        \r
131                 ::boost::exception_detail::throw_exception_(averror_protocol_not_found()<<                                                                              \r
132                         msg_info(av_error_str(ret)) <<                                                  \r
133                         source_info(narrow(source)) <<                                          \r
134                         boost::errinfo_api_function(func) <<                                    \r
135                         boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line);\r
136         case AVERROR_STREAM_NOT_FOUND:\r
137                 ::boost::exception_detail::throw_exception_(averror_stream_not_found()<<                                                                                \r
138                         msg_info(av_error_str(ret)) <<                                                  \r
139                         source_info(narrow(source)) <<                                          \r
140                         boost::errinfo_api_function(func) <<                                    \r
141                         boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line);\r
142         default:\r
143                 ::boost::exception_detail::throw_exception_(ffmpeg_error()<<                                                                            \r
144                         msg_info(av_error_str(ret)) <<                                                  \r
145                         source_info(narrow(source)) <<                                          \r
146                         boost::errinfo_api_function(func) <<                                    \r
147                         boost::errinfo_errno(AVUNERROR(ret)), local_func, file, line);\r
148         }\r
149 }\r
150 \r
151 static void throw_on_ffmpeg_error(int ret, const std::wstring& source, const char* func, const char* local_func, const char* file, int line)\r
152 {\r
153         throw_on_ffmpeg_error(ret, narrow(source).c_str(), func, local_func, file, line);\r
154 }\r
155 \r
156 \r
157 //#define THROW_ON_ERROR(ret, source, func) throw_on_ffmpeg_error(ret, source, __FUNC__, __FILE__, __LINE__)\r
158 \r
159 #define THROW_ON_ERROR_STR_(call) #call\r
160 #define THROW_ON_ERROR_STR(call) THROW_ON_ERROR_STR_(call)\r
161 \r
162 #define THROW_ON_ERROR(ret, func, source) \\r
163                 throw_on_ffmpeg_error(ret, source, func, __FUNCTION__, __FILE__, __LINE__);             \r
164 \r
165 #define THROW_ON_ERROR2(call, source)                                                                           \\r
166         [&]() -> int                                                                                                                    \\r
167         {                                                                                                                                               \\r
168                 int ret = call;                                                                                                         \\r
169                 throw_on_ffmpeg_error(ret, source, THROW_ON_ERROR_STR(call), __FUNCTION__, __FILE__, __LINE__); \\r
170                 return ret;                                                                                                                     \\r
171         }()\r
172 \r
173 #define LOG_ON_ERROR2(call, source)                                                                                     \\r
174         [&]() -> int                                                                                                                    \\r
175         {                                       \\r
176                 int ret = -1;\\r
177                 try{                                                                                                                            \\r
178                  ret = call;                                                                                                                    \\r
179                 throw_on_ffmpeg_error(ret, source, THROW_ON_ERROR_STR(call), __FUNCTION__, __FILE__, __LINE__); \\r
180                 return ret;                                                                                                                     \\r
181                 }catch(...){CASPAR_LOG_CURRENT_EXCEPTION();}                                            \\r
182                 return ret;                                                                                                                     \\r
183         }()\r
184 \r
185 }}