libexplain
1.4.D001
|
00001 /* 00002 * libexplain - a library of system-call-specific strerror replacements 00003 * Copyright (C) 2011, 2013 Peter Miller 00004 * Written by Peter Miller <pmiller@opensource.org.au> 00005 * 00006 * This program is free software; you can redistribute it and/or modify it 00007 * under the terms of the GNU Lesser General Public License as published by 00008 * the Free Software Foundation; either version 3 of the License, or (at your 00009 * option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, but WITHOUT 00012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 00014 * License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public License 00017 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00018 */ 00019 00020 #include <libexplain/ac/errno.h> 00021 #include <libexplain/ac/linux/videodev2.h> 00022 #include <libexplain/ac/string.h> 00023 #include <libexplain/ac/sys/ioctl.h> 00024 00025 #include <libexplain/buffer/einval.h> 00026 #include <libexplain/buffer/enotsup.h> 00027 #include <libexplain/buffer/is_the_null_pointer.h> 00028 #include <libexplain/buffer/v4l2_buffer.h> 00029 #include <libexplain/buffer/v4l2_buf_type.h> 00030 #include <libexplain/buffer/v4l2_memory.h> 00031 #include <libexplain/iocontrol/generic.h> 00032 #include <libexplain/iocontrol/vidioc_qbuf.h> 00033 #include <libexplain/is_efault.h> 00034 00035 #ifdef VIDIOC_QBUF 00036 00037 00038 static void 00039 print_data(const explain_iocontrol_t *p, explain_string_buffer_t *sb, 00040 int errnum, int fildes, int request, const void *data) 00041 { 00042 (void)p; 00043 (void)errnum; 00044 (void)fildes; 00045 (void)request; 00046 explain_buffer_v4l2_buffer(sb, data, 1); 00047 } 00048 00049 00050 static void 00051 print_explanation(const explain_iocontrol_t *p, explain_string_buffer_t *sb, 00052 int errnum, int fildes, int request, const void *data) 00053 { 00054 switch (errnum) 00055 { 00056 case EINVAL: 00057 if (!data) 00058 { 00059 explain_buffer_is_the_null_pointer(sb, "data"); 00060 return; 00061 } 00062 00063 { 00064 const struct v4l2_buffer *arg; 00065 00066 arg = data; 00067 if (explain_is_efault_pointer(arg, sizeof(*arg))) 00068 goto generic; 00069 00070 /* 00071 * Check the type (Linux kernel always does this first). 00072 */ 00073 switch (explain_v4l2_buf_type_check(fildes, arg->type)) 00074 { 00075 case explain_v4l2_buf_type_check_no_idea: 00076 default: 00077 break; 00078 00079 case explain_v4l2_buf_type_check_notsup: 00080 explain_buffer_enotsup_device(sb, "data->type"); 00081 return; 00082 00083 case explain_v4l2_buf_type_check_nosuch: 00084 explain_buffer_einval_vague(sb, "data->type"); 00085 return; 00086 00087 case explain_v4l2_buf_type_check_ok: 00088 break; 00089 } 00090 00091 /* 00092 * Check the frame number. 00093 */ 00094 { 00095 int nframes; 00096 00097 nframes = explain_v4l2_buffer_get_nframes(fildes, arg->type); 00098 if (nframes == 0) 00099 { 00100 explain_string_buffer_puts 00101 ( 00102 sb, 00103 /* FIXME: i18n */ 00104 "no frames have been allocated yet" 00105 ); 00106 return; 00107 } 00108 else if (nframes > 0 && arg->index >= (unsigned)nframes) 00109 { 00110 explain_buffer_einval_out_of_range 00111 ( 00112 sb, 00113 "data->index", 00114 0, 00115 nframes - 1 00116 ); 00117 return; 00118 } 00119 } 00120 00121 /* 00122 * check the memory mode 00123 */ 00124 { 00125 struct v4l2_buffer frinfo; 00126 00127 memset(&frinfo, 0, sizeof(frinfo)); 00128 frinfo.index = arg->index; 00129 frinfo.type = arg->type; 00130 if (ioctl(fildes, VIDIOC_QUERYBUF, &frinfo) >= 0) 00131 { 00132 if (arg->memory != frinfo.memory) 00133 { 00134 explain_buffer_einval_vague(sb, "data->memory"); 00135 00136 explain_string_buffer_puts(sb->footnotes, "; "); 00137 explain_string_buffer_puts 00138 ( 00139 sb->footnotes, 00140 /* FIXME: i18n */ 00141 "the current v4l2 memory mode is " 00142 ); 00143 explain_buffer_v4l2_memory 00144 ( 00145 sb->footnotes, 00146 frinfo.memory 00147 ); 00148 return; 00149 } 00150 } 00151 00152 if (frinfo.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE)) 00153 { 00154 explain_string_buffer_puts 00155 ( 00156 sb, 00157 /* FIXME: i18n */ 00158 "the frame buffer is already in use" 00159 ); 00160 return; 00161 } 00162 } 00163 } 00164 00165 /* no idea */ 00166 goto generic; 00167 00168 default: 00169 generic: 00170 explain_iocontrol_generic_print_explanation 00171 ( 00172 p, 00173 sb, 00174 errnum, 00175 fildes, 00176 request, 00177 data 00178 ); 00179 break; 00180 } 00181 } 00182 00183 00184 static void 00185 print_data_returned(const explain_iocontrol_t *p, explain_string_buffer_t *sb, 00186 int errnum, int fildes, int request, const void *data) 00187 { 00188 (void)p; 00189 (void)errnum; 00190 (void)fildes; 00191 (void)request; 00192 explain_buffer_v4l2_buffer(sb, data, 1); 00193 } 00194 00195 00196 const explain_iocontrol_t explain_iocontrol_vidioc_qbuf = 00197 { 00198 "VIDIOC_QBUF", /* name */ 00199 VIDIOC_QBUF, /* value */ 00200 0, /* disambiguate */ 00201 0, /* print_name */ 00202 print_data, 00203 print_explanation, 00204 print_data_returned, 00205 sizeof(struct v4l2_buffer), /* data_size */ 00206 "struct v4l2_buffer *", /* data_type */ 00207 0, /* flags */ 00208 __FILE__, 00209 __LINE__, 00210 }; 00211 00212 #else /* ndef VIDIOC_QBUF */ 00213 00214 const explain_iocontrol_t explain_iocontrol_vidioc_qbuf = 00215 { 00216 0, /* name */ 00217 0, /* value */ 00218 0, /* disambiguate */ 00219 0, /* print_name */ 00220 0, /* print_data */ 00221 0, /* print_explanation */ 00222 0, /* print_data_returned */ 00223 0, /* data_size */ 00224 0, /* data_type */ 00225 0, /* flags */ 00226 __FILE__, 00227 __LINE__, 00228 }; 00229 00230 #endif /* VIDIOC_QBUF */ 00231 00232 /* vim: set ts=8 sw=4 et : */