- Main Page
- Modules
- Namespaces
- Classes
- Files

- Search for |

- File List
- File Members

# samples/common/classes/NvV4l2Element.cpp

Go to the documentation of this file.

    00001 /*
    00002  * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
    00003  *
    00004  * Redistribution and use in source and binary forms, with or without
    00005  * modification, are permitted provided that the following conditions
    00006  * are met:
    00007  *  * Redistributions of source code must retain the above copyright
    00008  *    notice, this list of conditions and the following disclaimer.
    00009  *  * Redistributions in binary form must reproduce the above copyright
    00010  *    notice, this list of conditions and the following disclaimer in the
    00011  *    documentation and/or other materials provided with the distribution.
    00012  *  * Neither the name of NVIDIA CORPORATION nor the names of its
    00013  *    contributors may be used to endorse or promote products derived
    00014  *    from this software without specific prior written permission.
    00015  *
    00016  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
    00017  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    00018  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    00019  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    00020  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    00021  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    00022  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    00023  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
    00024  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    00026  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    00027  */
    00028
    00029 #include "NvV4l2Element.h"
    00030 #include "NvLogging.h"
    00031
    00032 #include <fcntl.h>
    00033 #include <cstring>
    00034 #include <errno.h>
    00035 #include <libv4l2.h>
    00036
    00037 #define CAT_NAME "V4l2Element"
    00038
    00039 using namespace std;
    00040
    00041 NvV4l2Element::NvV4l2Element(const char *comp_name, const char *dev_node, int flags, NvElementProfiler::ProfilerField fields)
    00042     :NvElement(comp_name, fields),
    00043       output_plane(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, comp_name,
    00044                   fd, !(flags & O_NONBLOCK), profiler),
    00045       capture_plane(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, comp_name,
    00046                   fd, !(flags & O_NONBLOCK), profiler)
    00047 {
    00048     struct v4l2_capability caps;
    00049     int ret;
    00050
    00051     app_data = NULL;
    00052     output_plane_pixfmt = 0;
    00053     capture_plane_pixfmt = 0;
    00054
    00055     fd = v4l2_open(dev_node, flags | O_RDWR);
    00056     if (fd == -1)
    00057     {
    00058         COMP_SYS_ERROR_MSG("Could not open device '" << dev_node << "'");
    00059         is_in_error = 1;
    00060         return;
    00061     }
    00062     COMP_DEBUG_MSG("Opened, fd = " << fd);
    00063
    00064     ret = v4l2_ioctl(fd, VIDIOC_QUERYCAP, &caps);
    00065     if (ret != 0)
    00066     {
    00067         COMP_SYS_ERROR_MSG("Error in VIDIOC_QUERYCAP");
    00068         is_in_error = 1;
    00069         return;
    00070     }
    00071     if (!(caps.capabilities & V4L2_CAP_VIDEO_M2M_MPLANE))
    00072     {
    00073         COMP_ERROR_MSG("Device does not support V4L2_CAP_VIDEO_M2M_MPLANE");
    00074         is_in_error = 1;
    00075         return;
    00076     }
    00077 }
    00078
    00079 NvV4l2Element::~NvV4l2Element()
    00080 {
    00081     output_plane.deinitPlane();
    00082     capture_plane.deinitPlane();
    00083
    00084     if (fd != -1)
    00085     {
    00086         v4l2_close(fd);
    00087         CAT_DEBUG_MSG("Device closed, fd = " << fd);
    00088     }
    00089 }
    00090
    00091 int
    00092 NvV4l2Element::dqEvent(struct v4l2_event &ev, uint32_t max_wait_ms)
    00093 {
    00094     int ret;
    00095
    00096     do
    00097     {
    00098         ret = v4l2_ioctl(fd, VIDIOC_DQEVENT, &ev);
    00099
    00100         if (ret == 0)
    00101         {
    00102             COMP_DEBUG_MSG("DQed event " << hex << ev.type << dec);
    00103         }
    00104         else if (errno != EAGAIN || max_wait_ms-- == 0)
    00105         {
    00106             COMP_SYS_ERROR_MSG("Error while DQing event");
    00107             break;
    00108         }
    00109         else
    00110         {
    00111             usleep(1000);
    00112         }
    00113     }
    00114     while (ret);
    00115
    00116     return ret;
    00117 }
    00118
    00119 int
    00120 NvV4l2Element::setControl(uint32_t id, int32_t value)
    00121 {
    00122     struct v4l2_control ctl;
    00123     int ret;
    00124
    00125     ctl.id = id;
    00126     ctl.value = value;
    00127
    00128     ret = v4l2_ioctl(fd, VIDIOC_S_CTRL, &ctl);
    00129
    00130     if (ret < 0)
    00131     {
    00132         COMP_SYS_ERROR_MSG("Error setting value " << value << " on control " <<
    00133                 id);
    00134     }
    00135     else
    00136     {
    00137         COMP_DEBUG_MSG("Set value " << value << " on control " << id);
    00138     }
    00139     return ret;
    00140 }
    00141
    00142 int
    00143 NvV4l2Element::getControl(uint32_t id, int32_t &value)
    00144 {
    00145     struct v4l2_control ctl;
    00146     int ret;
    00147
    00148     ctl.id = id;
    00149
    00150     ret = v4l2_ioctl(fd, VIDIOC_G_CTRL, &ctl);
    00151
    00152     if (ret < 0)
    00153     {
    00154         COMP_SYS_ERROR_MSG("Error getting value of control " << id);
    00155     }
    00156     else
    00157     {
    00158         COMP_DEBUG_MSG("Got value " << ctl.value << " for control " << id);
    00159         value = ctl.value;
    00160     }
    00161     return ret;
    00162 }
    00163
    00164 int
    00165 NvV4l2Element::setExtControls(v4l2_ext_controls &ctl)
    00166 {
    00167     int ret;
    00168
    00169     ret = v4l2_ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctl);
    00170
    00171     if (ret < 0)
    00172     {
    00173         COMP_SYS_ERROR_MSG("Error setting controls");
    00174     }
    00175     else
    00176     {
    00177         COMP_DEBUG_MSG("Set controls");
    00178     }
    00179     return ret;
    00180 }
    00181
    00182 int
    00183 NvV4l2Element::getExtControls(v4l2_ext_controls &ctl)
    00184 {
    00185     int ret;
    00186
    00187     ret = v4l2_ioctl(fd, VIDIOC_G_EXT_CTRLS, &ctl);
    00188
    00189     if (ret < 0)
    00190     {
    00191         COMP_SYS_ERROR_MSG("Error getting value of controls");
    00192     }
    00193     else
    00194     {
    00195         COMP_DEBUG_MSG("Got controls");
    00196     }
    00197     return ret;
    00198 }
    00199
    00200 int
    00201 NvV4l2Element::subscribeEvent(uint32_t type, uint32_t id, uint32_t flags)
    00202 {
    00203     struct v4l2_event_subscription sub;
    00204     int ret;
    00205
    00206     memset(&sub, 0, sizeof(struct v4l2_event_subscription));
    00207
    00208     sub.type = type;
    00209     sub.id = id;
    00210     sub.flags = flags;
    00211
    00212     ret = v4l2_ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
    00213     if (ret == 0)
    00214     {
    00215         COMP_DEBUG_MSG("Successfully subscribed to event " << type);
    00216     }
    00217     else
    00218     {
    00219         COMP_SYS_ERROR_MSG
    00220             ("Error while subscribing to event " << type);
    00221     }
    00222
    00223     return ret;
    00224 }
    00225
    00226 int
    00227 NvV4l2Element::abort()
    00228 {
    00229     int ret = 0;
    00230
    00231     ret |= output_plane.setStreamStatus(false);
    00232     ret |= capture_plane.setStreamStatus(false);
    00233
    00234     return ret;
    00235 }
    00236
    00237 int
    00238 NvV4l2Element::waitForIdle(uint32_t max_wait_ms)
    00239 {
    00240     COMP_ERROR_MSG("wait_for_idle not implemented");
    00241     return 0;
    00242 }
    00243
    00244 int
    00245 NvV4l2Element::isInError()
    00246 {
    00247     int error = is_in_error;
    00248     error |= capture_plane.isInError();
    00249     error |= output_plane.isInError();
    00250     return error;
    00251 }
    00252
    00253 void
    00254 NvV4l2Element::enableProfiling()
    00255 {
    00256     if (output_plane_pixfmt || capture_plane_pixfmt)
    00257     {
    00258         COMP_ERROR_MSG("Profiling must be enabled before setting formats on either plane");
    00259         return;
    00260     }
    00261     profiler.enableProfiling(true);
    00262 }