libexplain  1.4.D001
libexplain/iocontrol/vidioc_qbuf.c
Go to the documentation of this file.
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 : */