00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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 }