- Main Page
- Modules
- Namespaces
- Classes
- Files

- Search for |

- File List
- File Members

# samples/common/classes/NvVideoDecoder.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 "NvVideoDecoder.h"
    00030 #include "NvLogging.h"
    00031
    00032 #include <cstring>
    00033 #include <errno.h>
    00034 #include <libv4l2.h>
    00035
    00036 #define DECODER_DEV "/dev/nvhost-nvdec"
    00037 #define CAT_NAME "NVDEC"
    00038
    00039 #define CHECK_V4L2_RETURN(ret, str)              \
    00040     if (ret < 0) {                               \
    00041         COMP_SYS_ERROR_MSG(str << ": failed");   \
    00042         return -1;                               \
    00043     } else {                                     \
    00044         COMP_DEBUG_MSG(str << ": success");      \
    00045         return 0;                                \
    00046     }
    00047
    00048 #define RETURN_ERROR_IF_FORMATS_SET() \
    00049     if (output_plane_pixfmt != 0) { \
    00050         COMP_ERROR_MSG("Should be called before setting plane formats") \
    00051         return -1; \
    00052     }
    00053
    00054 #define RETURN_ERROR_IF_BUFFERS_REQUESTED() \
    00055     if (output_plane.getNumBuffers() != 0 && capture_plane.getNumBuffers() != 0) { \
    00056         COMP_ERROR_MSG("Should be called before requesting buffers on either plane") \
    00057         return -1; \
    00058     }
    00059
    00060 #define RETURN_ERROR_IF_FORMATS_NOT_SET() \
    00061     if (output_plane_pixfmt == 0) { \
    00062         COMP_ERROR_MSG("Should be called after setting plane formats") \
    00063         return -1; \
    00064     }
    00065
    00066 using namespace std;
    00067
    00068 NvVideoDecoder::NvVideoDecoder(const char *name, int flags)
    00069     :NvV4l2Element(name, DECODER_DEV, flags, valid_fields)
    00070 {
    00071 }
    00072
    00073 NvVideoDecoder *
    00074 NvVideoDecoder::createVideoDecoder(const char *name, int flags)
    00075 {
    00076     NvVideoDecoder *dec = new NvVideoDecoder(name, flags);
    00077     if (dec->isInError())
    00078     {
    00079         delete dec;
    00080         return NULL;
    00081     }
    00082     return dec;
    00083 }
    00084
    00085 NvVideoDecoder::~NvVideoDecoder()
    00086 {
    00087 }
    00088
    00089 int
    00090 NvVideoDecoder::setCapturePlaneFormat(uint32_t pixfmt, uint32_t width,
    00091         uint32_t height)
    00092 {
    00093     struct v4l2_format format;
    00094     uint32_t num_bufferplanes;
    00095     NvBuffer::NvBufferPlaneFormat planefmts[MAX_PLANES];
    00096
    00097     if (pixfmt != V4L2_PIX_FMT_NV12M)
    00098     {
    00099         COMP_ERROR_MSG("Only V4L2_PIX_FMT_NV12M is supported");
    00100         return -1;
    00101     }
    00102
    00103     capture_plane_pixfmt = pixfmt;
    00104     NvBuffer::fill_buffer_plane_format(&num_bufferplanes, planefmts, width,
    00105             height, pixfmt);
    00106     capture_plane.setBufferPlaneFormat(num_bufferplanes, planefmts);
    00107
    00108     memset(&format, 0, sizeof(struct v4l2_format));
    00109     format.type = capture_plane.getBufType();
    00110     format.fmt.pix_mp.width = width;
    00111     format.fmt.pix_mp.height = height;
    00112     format.fmt.pix_mp.pixelformat = pixfmt;
    00113     format.fmt.pix_mp.num_planes = num_bufferplanes;
    00114
    00115     return capture_plane.setFormat(format);
    00116 }
    00117
    00118 int
    00119 NvVideoDecoder::setOutputPlaneFormat(uint32_t pixfmt, uint32_t sizeimage)
    00120 {
    00121     struct v4l2_format format;
    00122
    00123     memset(&format, 0, sizeof(struct v4l2_format));
    00124     format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    00125     switch (pixfmt)
    00126     {
    00127         case V4L2_PIX_FMT_H264:
    00128         case V4L2_PIX_FMT_H265:
    00129             output_plane_pixfmt = pixfmt;
    00130             break;
    00131         default:
    00132             COMP_ERROR_MSG("Unsupported pixel format for decoder output plane "
    00133                     << pixfmt);
    00134             return -1;
    00135     }
    00136     format.fmt.pix_mp.pixelformat = pixfmt;
    00137     format.fmt.pix_mp.num_planes = 1;
    00138     format.fmt.pix_mp.plane_fmt[0].sizeimage = sizeimage;
    00139
    00140     return output_plane.setFormat(format);
    00141 }
    00142
    00143 int
    00144 NvVideoDecoder::disableDPB()
    00145 {
    00146     struct v4l2_ext_control control;
    00147     struct v4l2_ext_controls ctrls;
    00148
    00149     RETURN_ERROR_IF_FORMATS_NOT_SET();
    00150     RETURN_ERROR_IF_BUFFERS_REQUESTED();
    00151
    00152     memset(&control, 0, sizeof(control));
    00153     memset(&ctrls, 0, sizeof(ctrls));
    00154
    00155     ctrls.count = 1;
    00156     ctrls.controls = &control;
    00157
    00158     control.id = V4L2_CID_MPEG_VIDEO_DISABLE_DPB;
    00159
    00160     CHECK_V4L2_RETURN(setExtControls(ctrls),
    00161             "Disabling decoder DPB");
    00162 }
    00163
    00164 int
    00165 NvVideoDecoder::disableCompleteFrameInputBuffer()
    00166 {
    00167     struct v4l2_ext_control control;
    00168     struct v4l2_ext_controls ctrls;
    00169
    00170     RETURN_ERROR_IF_FORMATS_SET();
    00171
    00172     memset(&control, 0, sizeof(control));
    00173     memset(&ctrls, 0, sizeof(ctrls));
    00174
    00175     ctrls.count = 1;
    00176     ctrls.controls = &control;
    00177
    00178     control.id = V4L2_CID_MPEG_VIDEO_DISABLE_COMPLETE_FRAME_INPUT;
    00179
    00180     CHECK_V4L2_RETURN(setExtControls(ctrls),
    00181             "Disabling decoder complete frame input buffer");
    00182 }
    00183
    00184 int
    00185 NvVideoDecoder::getMinimumCapturePlaneBuffers(int &num)
    00186 {
    00187     CHECK_V4L2_RETURN(getControl(V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, num),
    00188             "Getting decoder minimum capture plane buffers (" << num << ")");
    00189 }
    00190
    00191 int
    00192 NvVideoDecoder::setSkipFrames(enum v4l2_skip_frames_type skip_frames)
    00193 {
    00194     struct v4l2_ext_control control;
    00195     struct v4l2_ext_controls ctrls;
    00196
    00197     RETURN_ERROR_IF_FORMATS_NOT_SET();
    00198     RETURN_ERROR_IF_BUFFERS_REQUESTED();
    00199
    00200     memset(&control, 0, sizeof(control));
    00201     memset(&ctrls, 0, sizeof(ctrls));
    00202
    00203     ctrls.count = 1;
    00204     ctrls.controls = &control;
    00205
    00206     control.id = V4L2_CID_MPEG_VIDEO_SKIP_FRAMES;
    00207     control.value = skip_frames;
    00208
    00209     CHECK_V4L2_RETURN(setExtControls(ctrls),
    00210             "Setting decoder skip frames to " << skip_frames);
    00211 }
    00212
    00213 int
    00214 NvVideoDecoder::enableMetadataReporting()
    00215 {
    00216     struct v4l2_ext_control control;
    00217     struct v4l2_ext_controls ctrls;
    00218
    00219     RETURN_ERROR_IF_FORMATS_NOT_SET();
    00220     RETURN_ERROR_IF_BUFFERS_REQUESTED();
    00221
    00222     memset(&control, 0, sizeof(control));
    00223     memset(&ctrls, 0, sizeof(ctrls));
    00224
    00225     ctrls.count = 1;
    00226     ctrls.controls = &control;
    00227
    00228     control.id = V4L2_CID_MPEG_VIDEO_ERROR_REPORTING;
    00229
    00230     CHECK_V4L2_RETURN(setExtControls(ctrls),
    00231             "Enabling decoder output metadata reporting");
    00232 }
    00233
    00234 int
    00235 NvVideoDecoder::getMetadata(uint32_t buffer_index,
    00236         v4l2_ctrl_videodec_outputbuf_metadata &dec_metadata)
    00237 {
    00238     v4l2_ctrl_video_metadata metadata;
    00239     struct v4l2_ext_control control;
    00240     struct v4l2_ext_controls ctrls;
    00241
    00242     ctrls.count = 1;
    00243     ctrls.controls = &control;
    00244
    00245     metadata.buffer_index = buffer_index;
    00246     metadata.VideoDecMetadata = &dec_metadata;
    00247
    00248     control.id = V4L2_CID_MPEG_VIDEODEC_METADATA;
    00249     control.string = (char *)&metadata;
    00250
    00251     CHECK_V4L2_RETURN(getExtControls(ctrls),
    00252             "Getting decoder output metadata for buffer " << buffer_index);
    00253 }