123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586 |
- /*
- * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of NVIDIA CORPORATION nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- /**
- * @file
- * <b>NVIDIA Multimedia API: V4L2 Element Plane</b>
- *
- * @b Description: This file declares a helper class for operations
- * performed on a V4L2 Element plane.
- */
- /**
- * @defgroup l4t_mm_nvv4lelementplane_group NvV4l2ElementPlane Class
- * @ingroup l4t_mm_nvelement_group
- *
- * Helper class for operations performed on a V4L2 element plane.
- * This includes getting/setting plane formats, plane buffers,
- * and cropping.
- * @{
- */
- #ifndef __NV_V4L2_ELELMENT_PLANE_H__
- #define __NV_V4L2_ELELMENT_PLANE_H__
- #include <pthread.h>
- #include "NvElement.h"
- #include "NvLogging.h"
- #include "NvBuffer.h"
- /**
- * Prints a plane-specific message of level LOG_LEVEL_DEBUG.
- * Must not be used by applications.
- */
- #define PLANE_DEBUG_MSG(str) COMP_DEBUG_MSG(plane_name << ":" << str);
- /**
- * Prints a plane-specific message of level LOG_LEVEL_INFO.
- * Must not be used by applications.
- */
- #define PLANE_INFO_MSG(str) COMP_INFO_MSG(plane_name << ":" << str);
- /**
- * Prints a plane-specific message of level LOG_LEVEL_WARN.
- * Must not be used by applications.
- */
- #define PLANE_WARN_MSG(str) COMP_WARN_MSG(plane_name << ":" << str);
- /**
- * Prints a plane-specific message of level LOG_LEVEL_ERROR.
- * Must not be used by applications.
- */
- #define PLANE_ERROR_MSG(str) COMP_ERROR_MSG(plane_name << ":" << str);
- /**
- * Prints a plane-specific system error message of level LOG_LEVEL_ERROR.
- * Must not be used by applications.
- */
- #define PLANE_SYS_ERROR_MSG(str) COMP_SYS_ERROR_MSG(plane_name << ":" << str);
- /**
- * @brief Defines a helper class for operations performed on a V4L2 Element plane.
- *
- * This derived class is modeled on the planes of a V4L2 Element. It provides
- * convenient wrapper methods around V4L2 IOCTLs associated with plane
- * operations such as <code>VIDIOC_G_FMT/VIDIOC_S_FMT</code>, \c VIDIOC_REQBUFS,
- * <code>VIDIOC_STREAMON/VIDIOC_STREAMOFF</code>, etc.
- *
- * The plane buffer type can be either \c V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE (for
- * the output plane) or \c V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE (for the capture
- * plane).
- *
- * The plane has an array of NvBuffer object pointers that is allocated and
- * initialized during reqbuf call. These \c NvBuffer objects are similar to the
- * \c v4l2_buffer structures that are queued/dequeued.
- *
- * This class provides another feature useful for multi-threading. On calling
- * #startDQThread, it internally spawns a thread that runs infinitely until
- * signaled to stop. This thread keeps trying to dequeue a buffer from the
- * plane and calls a #dqThreadCallback method specified by the user on
- * successful dequeue.
- *
- */
- class NvV4l2ElementPlane
- {
- public:
- /**
- * Gets the plane format.
- *
- * Calls @b VIDIOC_G_FMT \c IOCTL internally.
- *
- * @param[in,out] format A reference to the \c v4l2_format structure to be filled.
- * @return 0 for success, -1 otherwise.
- */
- int getFormat(struct v4l2_format & format);
- /**
- * Sets the plane format.
- *
- * Calls @b VIDIOC_S_FMT \c IOCTL internally.
- *
- * @param[in] format A reference to the \c v4l2_format structure to be set on the plane.
- * @return 0 for success, -1 otherwise.
- */
- int setFormat(struct v4l2_format & format);
- /**
- * Maps the NvMMBuffer to NvBuffer for V4L2_MEMORY_DMABUF.
- *
- * @param[in] v4l2_buf Address of the NvBuffer to which the NvMMBuffer is mapped.
- * @param[in] dmabuff_fd Index to the field that holds NvMMBuffer attributes.
- * @return 0 for success, -1 otherwise.
- */
- int mapOutputBuffers(struct v4l2_buffer &v4l2_buf, int dmabuff_fd);
- /**
- * Unmaps the NvMMBuffer for V4L2_MEMORY_DMABUF.
- *
- * @param[in] index for the current buffer index.
- * @param[in] dmabuff_fd Index to the field that holds NvMMBuffer attributes.
- * @return 0 for success, -1 otherwise.
- */
- int unmapOutputBuffers(int index, int dmabuff_fd);
- /**
- * Gets the cropping rectangle for the plane.
- *
- * Calls @b VIDIOC_G_CROP \c IOCTL internally.
- *
- * @param[in] crop A reference to the \c v4l2_crop structure to be filled.
- * @return 0 for success, -1 otherwise.
- */
- int getCrop(struct v4l2_crop & crop);
- /**
- * Sets the selection rectangle for the plane.
- *
- * Calls @b VIDIOC_S_SELECTION IOCTL internally.
- *
- * @param[in] target Specifies the rectangle selection type.
- * @param[in] flags Specifies the flags to control selection adjustments.
- * @param[in] rect A reference to the selection rectangle.
- * @return 0 for success, -1 otherwise.
- */
- int setSelection(uint32_t target, uint32_t flags, struct v4l2_rect & rect);
- /**
- * Requests for buffers on the plane.
- *
- * Calls \c VIDIOC_REQBUFS IOCTL internally. Creates an array of NvBuffer of
- * length equal to the count returned by the IOCTL.
- *
- * @param[in] mem_type Specifies the type of V4L2 memory to be requested.
- * @param[in] num Specifies the number of buffers to request on the plane.
- * @return 0 for success, -1 otherwise.
- */
- int reqbufs(enum v4l2_memory mem_type, uint32_t num);
- /**
- * Queries the status of the buffer at the index.
- *
- * @warning This method works only for \c V4L2_MEMORY_MMAP memory.
- *
- * Calls \c VIDIOC_QUERYBUF IOCTL internally. Populates the \a length and \a
- * mem_offset members of all the NvBuffer::NvBufferPlane members of the
- * \c %NvBuffer object at index \a buf_index.
- *
- * @param[in] buf_index Specifies the index of the buffer to query.
- * @return 0 for success, -1 otherwise.
- */
- int queryBuffer(uint32_t buf_index);
- /**
- * Exports the buffer as DMABUF FD.
- *
- * @warning This method works only for \c V4L2_MEMORY_MMAP memory.
- *
- * Calls \c VIDIOC_EXPBUF IOCTL internally. Populates the \a fd member of all
- * the \c NvBuffer::NvBufferPlane members of \c NvBuffer object at index \a buf_in.
- *
- * @param[in] buf_index Specifies the index of the buffer to export.
- * @return 0 for success, -1 otherwise.
- */
- int exportBuffer(uint32_t buf_index);
- /**
- * Starts or stops streaming on the plane.
- *
- * Calls \c VIDIOC_STREAMON/VIDIOC_STREAMOFF IOCTLs internally.
- *
- * @param[in] status Must be TRUE to start the stream, FALSE to stop the stream.
- * @return 0 for success, -1 otherwise.
- */
- int setStreamStatus(bool status);
- /**
- * Checks whether the plane is streaming.
- *
- * @returns true if the plane is streaming, false otherwise.
- */
- bool getStreamStatus();
- /**
- * Sets streaming parameters.
- *
- * Calls \c VIDIOC_S_PARM IOCTL internally.
- *
- * @param[in] parm A reference to the \c v4l2_streamparm structure to be set on the
- * plane.
- * @return 0 for success, -1 otherwise.
- */
- int setStreamParms(struct v4l2_streamparm & parm);
- /**
- * Helper method that encapsulates all the method calls required to
- * set up the plane for streaming.
- *
- * Calls reqbuf internally. Then, for each of the buffers, calls #queryBuffer,
- * #exportBuffer and maps the buffer/allocates the buffer memory depending
- * on the memory type.
- *
- * @sa deinitPlane
- *
- * @param[in] mem_type V4L2 Memory to use on the buffer.
- * @param[in] num_buffers Number of buffer to request on the plane.
- * @param[in] map boolean value indicating if the buffers should be mapped to
- memory (Only for V4L2_MEMORY_MMAP).
- * @param[in] allocate boolean valued indicating whether the buffers should be
- allocated memory (Only for V4L2_MEMORY_USERPTR).
- * @return 0 for success, -1 otherwise.
- */
- int setupPlane(enum v4l2_memory mem_type, uint32_t num_buffers, bool map, bool allocate);
- /**
- * Helper method that encapsulates all the method calls required to
- * deinitialize the plane for streaming.
- *
- * For each of the buffers, unmaps/deallocates memory depending on the
- * memory type. Then, calls reqbuf with count zero.
- *
- * @sa setupPlane
- */
- void deinitPlane();
- /**
- * Gets the streaming/buffer type of this plane.
- *
- * @returns Type of the buffer belonging to enum \c v4l2_buf_type.
- */
- inline enum v4l2_buf_type getBufType()
- {
- return buf_type;
- }
- /**
- * Gets the \c NvBuffer object at index n.
- *
- * @returns \c %NvBuffer object at index n, NULL if n >= number of buffers.
- */
- NvBuffer *getNthBuffer(uint32_t n);
- /**
- * Dequeues a buffer from the plane.
- *
- * This is a blocking call. This call returns when a buffer is successfully
- * dequeued or timeout is reached. If \a buffer is not NULL, returns the
- * \c NvBuffer object at the index returned by the \c VIDIOC_DQBUF IOCTL. If this
- * plane shares a buffer with other elements and \a shared_buffer is not
- * NULL, returns the shared \c %NvBuffer object in \a shared_buffer.
- *
- * @param[in] v4l2_buf A reference to the \c v4l2_buffer structure to use for dequeueing.
- * @param[out] buffer Returns a pointer to a pointer to the \c %NvBuffer object associated with the dequeued
- * buffer. Can be NULL.
- * @param[out] shared_buffer Returns a pointer to a pointer to the shared \c %NvBuffer object if the queued
- buffer is shared with other elements. Can be NULL.
- * @param[in] num_retries Number of times to try dequeuing a buffer before
- * a failure is returned. In case of non-blocking
- * mode, this is equivalent to the number of
- * milliseconds to try to dequeue a buffer.
- * @return 0 for success, -1 otherwise.
- */
- int dqBuffer(struct v4l2_buffer &v4l2_buf, NvBuffer ** buffer,
- NvBuffer ** shared_buffer, uint32_t num_retries);
- /**
- * Queues a buffer on the plane.
- *
- * This method calls \c VIDIOC_QBUF internally. If this plane is sharing a
- * buffer with other elements, the application can pass the pointer to the
- * shared NvBuffer object in \a shared_buffer.
- *
- * @param[in] v4l2_buf A reference to the \c v4l2_buffer structure to use for queueing.
- * @param[in] shared_buffer A pointer to the shared \c %NvBuffer object.
- * @return 0 for success, -1 otherwise.
- */
- int qBuffer(struct v4l2_buffer &v4l2_buf, NvBuffer * shared_buffer);
- /**
- * Gets the number of buffers allocated/requested on the plane.
- *
- * @returns Number of buffers.
- */
- inline uint32_t getNumBuffers()
- {
- return num_buffers;
- }
- /**
- * Gets the number of planes buffers on this plane for the currently
- * set format.
- *
- * @returns Number of planes.
- */
- inline uint32_t getNumPlanes()
- {
- return n_planes;
- }
- /**
- * Sets the format of the planes of the buffer that is used with this
- * plane.
- *
- * The buffer plane format must be set before calling reqbuf since
- * these are needed by the NvBuffer constructor.
- *
- * @sa reqbufs
- *
- * @param[in] n_planes Number of planes in the buffer.
- * @param[in] planefmts A pointer to the array of \c NvBufferPlaneFormat that describes the
- * format of each of the plane. The array length must be at
- * least @a n_planes.
- */
- void setBufferPlaneFormat(int n_planes, NvBuffer::NvBufferPlaneFormat * planefmts);
- /**
- * Gets the number of buffers currently queued on the plane.
- *
- * @returns Number of buffers currently queued on the plane.
- */
- inline uint32_t getNumQueuedBuffers()
- {
- return num_queued_buffers;
- }
- /**
- * Gets the total number of buffers dequeued from the plane.
- *
- * @returns Total number of buffers dequeued from the plane.
- */
- inline uint32_t getTotalDequeuedBuffers()
- {
- return total_dequeued_buffers;
- }
- /**
- * Gets the total number of buffers queued on the plane.
- *
- * @returns Total number of buffers queued on the plane.
- */
- inline uint32_t getTotalQueuedBuffers()
- {
- return total_queued_buffers;
- }
- /**
- * Waits until all buffers of the plane are queued.
- *
- * This is a blocking call that returns when all the buffers are queued
- * or timeout is reached.
- * @param[in] max_wait_ms Maximum time to wait, in milliseconds.
- * @return 0 for success, -1 otherwise.
- */
- int waitAllBuffersQueued(uint32_t max_wait_ms);
- /**
- * Waits until all buffers of the plane are dequeued.
- *
- * This is a blocking call that returns when all the buffers are dequeued
- * or timeout is reached.
- * @param[in] max_wait_ms Maximum time to wait, in milliseconds
- * @return 0 for success, -1 otherwise.
- */
- int waitAllBuffersDequeued(uint32_t max_wait_ms);
- /**
- * This is a callback function type method that is called by the DQ Thread when
- * it successfully dequeues a buffer from the plane. Applications must implement
- * this and set the callback using #setDQThreadCallback.
- *
- * Setting the stream to off automatically stops this thread.
- *
- * @sa setDQThreadCallback, #startDQThread
- *
- * @param v4l2_buf A pointer to the \c v4l2_buffer structure that is used for dequeueing.
- * @param buffer A pointer to the NvBuffer object at the \c index contained in \c v4l2_buf.
- * @param shared_buffer A pointer to the NvBuffer object if the plane shares a buffer with other elements,
- * else NULL.
- * @param data A pointer to application specific data that is set with
- * #startDQThread.
- * @returns If the application implementing this call returns FALSE,
- * the DQThread is stopped; else, the DQ Thread continues running.
- */
- typedef bool(*dqThreadCallback) (struct v4l2_buffer * v4l2_buf,
- NvBuffer * buffer, NvBuffer * shared_buffer,
- void *data);
- /**
- * Sets the DQ Thread callback method.
- *
- * The callback method is called from the DQ Thread once a buffer is
- * successfully dequeued.
- * @param[in] callback Method to be called upon succesful dequeue.
- * @returns TRUE for success, FALSE for failure.
- */
- bool setDQThreadCallback(dqThreadCallback callback);
- /**
- * Starts DQ Thread.
- *
- * This method starts a thread internally. On successful dequeue of a
- * buffer from the plane, the #dqThreadCallback method set using
- * #setDQThreadCallback is called.
- *
- * Setting the stream to off automatically stops the thread.
- *
- * @sa stopDQThread, waitForDQThread
- *
- * @param[in] data A pointer to the application data. This is provided as an
- * argument in the \c dqThreadCallback method.
- * @return 0 for success, -1 otherwise.
- */
- int startDQThread(void *data);
- /**
- * Force stops the DQ Thread if it is running.
- *
- * Does not work when the device is opened in blocking mode.
- *
- * @sa startDQThread, waitForDQThread
- *
- * @return 0 for success, -1 otherwise.
- */
- int stopDQThread();
- /**
- * Waits for the DQ Thread to stop.
- *
- * This method waits until the DQ Thread stops or timeout is reached.
- *
- * @sa startDQThread, stopDQThread
- *
- * @param[in] max_wait_ms Maximum wait time, in milliseconds.
- * @return 0 for success, -1 otherwise.
- */
- int waitForDQThread(uint32_t max_wait_ms);
- pthread_mutex_t plane_lock; /**< Mutex lock used along with #plane_cond. */
- pthread_cond_t plane_cond; /**< Plane condition that application can wait on
- to receive notifications from
- #qBuffer/#dqBuffer. */
- private:
- int &fd; /**< A reference to the FD of the V4l2 Element the plane is associated with. */
- const char *plane_name; /**< A pointer to the name of the plane. Could be "Output Plane" or
- "Capture Plane". Used only for debug logs. */
- enum v4l2_buf_type buf_type; /**< Speciifes the type of the stream. */
- bool blocking; /**< Specifies whether the V4l2 element is opened with
- blocking mode. */
- uint32_t num_buffers; /**< Holds the number of buffers returned by \c VIDIOC_REQBUFS
- IOCTL. */
- NvBuffer **buffers; /**< A pointer to an array of NvBuffer object pointers. This array is
- allocated and initialized in #reqbufs. */
- uint8_t n_planes; /**< Specifies the number of planes in the buffers. */
- NvBuffer::NvBufferPlaneFormat planefmts[MAX_PLANES];
- /**< Format of the buffer planes. This must be
- initialized before calling #reqbufs since this
- is required by the \c %NvBuffer constructor. */
- enum v4l2_memory memory_type; /**< Specifies the V4l2 memory type of the buffers. */
- uint32_t num_queued_buffers; /**< Holds the number of buffers currently queued on the
- plane. */
- uint32_t total_queued_buffers; /**< Holds the total number of buffers queued on the
- plane. */
- uint32_t total_dequeued_buffers; /**< Holds the total number of buffers dequeued from
- the plane. */
- bool streamon; /**< Specifies whether the plane is streaming. */
- bool dqthread_running; /**< Specifies whether DQ Thread is running.
- Its value is toggled by the DQ Thread. */
- bool stop_dqthread; /**< Specifies the value used to signal the DQ Thread to stop. */
- pthread_t dq_thread; /**< Speciifes the pthread ID of the DQ Thread. */
- dqThreadCallback callback; /**< Specifies the callback method used by the DQ Thread. */
- void *dqThread_data; /**< Application supplied pointer provided as an
- argument in #dqThreadCallback. */
- /**
- * The DQ thread method.
- *
- * This method runs indefinitely until it is signaled to stop
- * by #stopDQThread or the #dqThreadCallback method returns FALSE.
- * It keeps on trying to dequeue a buffer from the plane and calls the
- * #dqThreadCallback method on successful dequeue.
- *
- * @param[in] v4l2_element_plane A pointer to the NvV4l2ElementPlane object
- * for which the thread started.
- */
- static void *dqThread(void *v4l2_element_plane);
- NvElementProfiler &v4l2elem_profiler; /**< A reference to the profiler belonging
- to the plane's parent element. */
- /**
- * Indicates whether the plane encountered an error during its operation.
- *
- * @return 0 if no error was encountered, a non-zero value if an
- * error was encountered.
- */
- inline int isInError()
- {
- return is_in_error;
- }
- /**
- * Creates a new V4l2Element plane.
- *
- *
- * @param[in] buf_type Type of the stream.
- * @param[in] device_name A pointer to the name of the element the plane belongs to.
- * @param[in] fd A reference to the FD of the device opened using v4l2_open.
- * @param[in] blocking A flag that indicates whether the device has been opened with blocking mode.
- * @param[in] profiler The profiler.
- */
- NvV4l2ElementPlane(enum v4l2_buf_type buf_type, const char *device_name,
- int &fd, bool blocking, NvElementProfiler &profiler);
- /**
- * Disallows copy constructor.
- */
- NvV4l2ElementPlane(const NvV4l2ElementPlane& that);
- /**
- * Disallows assignment.
- */
- void operator=(NvV4l2ElementPlane const&);
- /**
- * NvV4l2ElementPlane destructor.
- *
- * Calls #deinitPlane internally.
- */
- ~NvV4l2ElementPlane();
- int is_in_error; /**< Indicates if an error was encountered during
- the operation of the element. */
- const char *comp_name; /**< Specifies the name of the component,
- for debugging. */
- friend class NvV4l2Element;
- };
- /** @} */
- #endif
|