- Main Page
- Modules
- Namespaces
- Classes
- Files

- Search for |

- File List
- File Members

# samples/common/classes/NvVideoConverter.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 "NvVideoConverter.h"
    00030 #include "NvLogging.h"
    00031
    00032 #include <cstring>
    00033 #include <errno.h>
    00034
    00035 #define CONVERTER_DEV "/dev/nvhost-vic"
    00036 #define CAT_NAME "NVVIDCONV"
    00037
    00038 #define CHECK_V4L2_RETURN(ret, str)              \
    00039     if (ret < 0) {                               \
    00040         COMP_SYS_ERROR_MSG(str << ": failed");   \
    00041         return -1;                               \
    00042     } else {                                     \
    00043         COMP_DEBUG_MSG(str << ": success");      \
    00044         return 0;                                \
    00045     }
    00046
    00047 #define RETURN_ERROR_IF_FORMATS_SET() \
    00048     if (output_plane_pixfmt != 0 || capture_plane_pixfmt != 0) { \
    00049         COMP_ERROR_MSG("Should be called before setting plane formats") \
    00050         return -1; \
    00051     }
    00052
    00053 #define RETURN_ERROR_IF_BUFFERS_REQUESTED() \
    00054     if (output_plane.getNumBuffers() != 0 && capture_plane.getNumBuffers() != 0) { \
    00055         COMP_ERROR_MSG("Should be called before requesting buffers on either plane") \
    00056         return -1; \
    00057     }
    00058
    00059 #define RETURN_ERROR_IF_FORMATS_NOT_SET() \
    00060     if (output_plane_pixfmt == 0 || capture_plane_pixfmt == 0) { \
    00061         COMP_ERROR_MSG("Should be called after setting plane formats") \
    00062         return -1; \
    00063     }
    00064
    00065 using namespace std;
    00066
    00067 NvVideoConverter::NvVideoConverter(const char *name, int flags)
    00068     :NvV4l2Element(name, CONVERTER_DEV, flags, valid_fields)
    00069 {
    00070 }
    00071
    00072 NvVideoConverter *
    00073 NvVideoConverter::createVideoConverter(const char *name, int flags)
    00074 {
    00075     NvVideoConverter *conv = new NvVideoConverter(name, flags);
    00076     if (conv->isInError())
    00077     {
    00078         delete conv;
    00079         return NULL;
    00080     }
    00081     return conv;
    00082 }
    00083
    00084 NvVideoConverter::~NvVideoConverter()
    00085 {
    00086 }
    00087
    00088 int
    00089 NvVideoConverter::setCapturePlaneFormat(uint32_t pixfmt, uint32_t width,
    00090         uint32_t height, enum v4l2_nv_buffer_layout type)
    00091 {
    00092     struct v4l2_format format;
    00093     uint32_t num_bufferplanes;
    00094     NvBuffer::NvBufferPlaneFormat planefmts[MAX_PLANES];
    00095
    00096     if (setCapturePlaneBufferLayout(type) < 0)
    00097     {
    00098         return -1;
    00099     }
    00100
    00101     capture_plane_pixfmt = pixfmt;
    00102     NvBuffer::fill_buffer_plane_format(&num_bufferplanes, planefmts, width,
    00103             height, pixfmt);
    00104     capture_plane.setBufferPlaneFormat(num_bufferplanes, planefmts);
    00105
    00106     memset(&format, 0, sizeof(struct v4l2_format));
    00107     format.type = capture_plane.getBufType();
    00108     format.fmt.pix_mp.width = width;
    00109     format.fmt.pix_mp.height = height;
    00110     format.fmt.pix_mp.pixelformat = pixfmt;
    00111     format.fmt.pix_mp.num_planes = num_bufferplanes;
    00112
    00113     CHECK_V4L2_RETURN(capture_plane.setFormat(format),
    00114             "Setting capture plane format");
    00115 }
    00116
    00117 int
    00118 NvVideoConverter::setOutputPlaneFormat(uint32_t pixfmt, uint32_t width,
    00119         uint32_t height, enum v4l2_nv_buffer_layout type)
    00120 {
    00121     struct v4l2_format format;
    00122     uint32_t num_bufferplanes;
    00123     NvBuffer::NvBufferPlaneFormat planefmts[MAX_PLANES];
    00124
    00125     if (setOutputPlaneBufferLayout(type) < 0)
    00126     {
    00127         return -1;
    00128     }
    00129
    00130     output_plane_pixfmt = pixfmt;
    00131     NvBuffer::fill_buffer_plane_format(&num_bufferplanes, planefmts, width,
    00132             height, pixfmt);
    00133     output_plane.setBufferPlaneFormat(num_bufferplanes, planefmts);
    00134
    00135     memset(&format, 0, sizeof(struct v4l2_format));
    00136     format.type = output_plane.getBufType();
    00137     format.fmt.pix_mp.width = width;
    00138     format.fmt.pix_mp.height = height;
    00139     format.fmt.pix_mp.pixelformat = pixfmt;
    00140     format.fmt.pix_mp.num_planes = num_bufferplanes;
    00141
    00142     CHECK_V4L2_RETURN(output_plane.setFormat(format),
    00143             "Setting output plane format");
    00144 }
    00145
    00146 int
    00147 NvVideoConverter::waitForIdle(uint32_t max_wait_ms)
    00148 {
    00149     struct timespec timeToWait;
    00150     struct timeval now;
    00151     int return_val = 0;
    00152     int ret;
    00153
    00154     gettimeofday(&now, NULL);
    00155
    00156     timeToWait.tv_nsec = (now.tv_usec + (max_wait_ms % 1000) * 1000L) * 1000L;
    00157     timeToWait.tv_sec = now.tv_sec + max_wait_ms / 1000 +
    00158         timeToWait.tv_nsec / 1000000000L;
    00159     timeToWait.tv_nsec = timeToWait.tv_nsec % 1000000000L;
    00160
    00161     pthread_mutex_lock(&capture_plane.plane_lock);
    00162     while (output_plane.getTotalQueuedBuffers() >
    00163            capture_plane.getTotalDequeuedBuffers())
    00164     {
    00165         if (!capture_plane.getStreamStatus())
    00166         {
    00167             return_val = -2;
    00168             break;
    00169         }
    00170         ret = pthread_cond_timedwait(&capture_plane.plane_cond,
    00171                 &capture_plane.plane_lock, &timeToWait);
    00172         if (ret == ETIMEDOUT)
    00173         {
    00174             return_val = -1;
    00175             break;
    00176         }
    00177     }
    00178     pthread_mutex_unlock(&capture_plane.plane_lock);
    00179
    00180     return return_val;
    00181 }
    00182
    00183 int
    00184 NvVideoConverter::setOutputPlaneBufferLayout(enum v4l2_nv_buffer_layout type)
    00185 {
    00186     struct v4l2_ext_control ctl;
    00187     struct v4l2_ext_controls controls;
    00188
    00189     RETURN_ERROR_IF_BUFFERS_REQUESTED();
    00190
    00191     memset(&ctl, 0, sizeof(ctl));
    00192     memset(&controls, 0, sizeof(controls));
    00193
    00194     ctl.id = V4L2_CID_VIDEO_CONVERT_OUTPUT_PLANE_LAYOUT;
    00195     ctl.value = (uint32_t) type;
    00196     controls.controls = &ctl;
    00197     controls.count = 1;
    00198
    00199     CHECK_V4L2_RETURN(setExtControls(controls),
    00200             "Setting output plane buffer layout to " << type);
    00201 }
    00202
    00203 int
    00204 NvVideoConverter::setCapturePlaneBufferLayout(enum v4l2_nv_buffer_layout type)
    00205 {
    00206     struct v4l2_ext_control ctl;
    00207     struct v4l2_ext_controls controls;
    00208
    00209     RETURN_ERROR_IF_BUFFERS_REQUESTED();
    00210
    00211     memset(&ctl, 0, sizeof(ctl));
    00212     memset(&controls, 0, sizeof(controls));
    00213
    00214     ctl.id = V4L2_CID_VIDEO_CONVERT_CAPTURE_PLANE_LAYOUT;
    00215     ctl.value = (uint32_t) type;
    00216     controls.controls = &ctl;
    00217     controls.count = 1;
    00218
    00219     CHECK_V4L2_RETURN(setExtControls(controls),
    00220             "Setting capture plane buffer layout to " << type);
    00221 }
    00222
    00223 int
    00224 NvVideoConverter::setInterpolationMethod(enum v4l2_interpolation_method method)
    00225 {
    00226     struct v4l2_ext_control ctl;
    00227     struct v4l2_ext_controls controls;
    00228
    00229     RETURN_ERROR_IF_BUFFERS_REQUESTED();
    00230
    00231     memset(&ctl, 0, sizeof(ctl));
    00232     memset(&controls, 0, sizeof(controls));
    00233
    00234     ctl.id = V4L2_CID_VIDEO_CONVERT_INTERPOLATION_METHOD;
    00235     ctl.value = (uint32_t) method;
    00236     controls.controls = &ctl;
    00237     controls.count = 1;
    00238
    00239     CHECK_V4L2_RETURN(setExtControls(controls),
    00240             "Setting interpolation method to " << method);
    00241 }
    00242
    00243 int
    00244 NvVideoConverter::setFlipMethod(enum v4l2_flip_method method)
    00245 {
    00246     struct v4l2_ext_control ctl;
    00247     struct v4l2_ext_controls controls;
    00248
    00249     RETURN_ERROR_IF_BUFFERS_REQUESTED();
    00250
    00251     memset(&ctl, 0, sizeof(ctl));
    00252     memset(&controls, 0, sizeof(controls));
    00253
    00254     ctl.id = V4L2_CID_VIDEO_CONVERT_FLIP_METHOD;
    00255     ctl.value = (uint32_t) method;
    00256     controls.controls = &ctl;
    00257     controls.count = 1;
    00258
    00259     CHECK_V4L2_RETURN(setExtControls(controls),
    00260             "Setting flip method to " << method);
    00261 }
    00262
    00263 int
    00264 NvVideoConverter::setTnrAlgorithm(enum v4l2_tnr_algorithm algorithm)
    00265 {
    00266     struct v4l2_ext_control ctl;
    00267     struct v4l2_ext_controls controls;
    00268
    00269     RETURN_ERROR_IF_BUFFERS_REQUESTED();
    00270
    00271     memset(&ctl, 0, sizeof(ctl));
    00272     memset(&controls, 0, sizeof(controls));
    00273
    00274     ctl.id = V4L2_CID_VIDEO_CONVERT_TNR_ALGORITHM;
    00275     ctl.value = (uint32_t) algorithm;
    00276     controls.controls = &ctl;
    00277     controls.count = 1;
    00278
    00279     CHECK_V4L2_RETURN(setExtControls(controls),
    00280             "Setting TNR algorithm to " << algorithm);
    00281 }
    00282
    00283 int
    00284 NvVideoConverter::setCropRect(uint32_t left, uint32_t top, uint32_t width,
    00285             uint32_t height)
    00286 {
    00287     struct v4l2_rect rect;
    00288
    00289     rect.left = left;
    00290     rect.top = top;
    00291     rect.width = width;
    00292     rect.height = height;
    00293
    00294     CHECK_V4L2_RETURN(capture_plane.setSelection(V4L2_SEL_TGT_CROP, 0, rect),
    00295             "Setting crop rectangle to left=" << left << ", top=" << top <<
    00296             ", width=" << width << ", height=" << height);
    00297 }