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