- Main Page
- Modules
- Namespaces
- Classes
- Files

- Search for |

- File List
- File Members

# include/NvV4l2ElementPlane.h

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 /**
    00030  * @file NvV4l2ElementPlane.h
    00031  *
    00032  * @brief Helper Class for operations performed on a V4L2 Element plane
    00033  */
    00034
    00035 #ifndef __NV_V4L2_ELELMENT_PLANE_H__
    00036 #define __NV_V4L2_ELELMENT_PLANE_H__
    00037
    00038 #include <pthread.h>
    00039 #include "NvElement.h"
    00040 #include "NvLogging.h"
    00041 #include "NvBuffer.h"
    00042
    00043 /**
    00044  * Prints a plane specific message of level #LOG_LEVEL_DEBUG.
    00045  * Should not be used by applications.
    00046  */
    00047 #define PLANE_DEBUG_MSG(str) COMP_DEBUG_MSG(plane_name << ":" << str);
    00048 /**
    00049  * Prints a plane specific message of level #LOG_LEVEL_INFO.
    00050  * Should not be used by applications.
    00051  */
    00052 #define PLANE_INFO_MSG(str) COMP_INFO_MSG(plane_name << ":" << str);
    00053 /**
    00054  * Prints a plane specific message of level #LOG_LEVEL_WARN.
    00055  * Should not be used by applications.
    00056  */
    00057 #define PLANE_WARN_MSG(str) COMP_WARN_MSG(plane_name << ":" << str);
    00058 /**
    00059  * Prints a plane specific message of level #LOG_LEVEL_ERROR.
    00060  * Should not be used by applications.
    00061  */
    00062 #define PLANE_ERROR_MSG(str) COMP_ERROR_MSG(plane_name << ":" << str);
    00063 /**
    00064  * Prints a plane specific system error message of level #LOG_LEVEL_ERROR.
    00065  * Should not be used by applications.
    00066  */
    00067 #define PLANE_SYS_ERROR_MSG(str) COMP_SYS_ERROR_MSG(plane_name << ":" << str);
    00068
    00069 /**
    00070  * @brief Helper Class for operations performed on a V4L2 Element plane.
    00071  *
    00072  * This class is modelled on the planes of a V4L2 Element. It provides
    00073  * convenient wrapper functions around V4L2 ioctls associated with plane
    00074  * operations such as VIDIOC_G_FMT/VIDIOC_S_FMT, VIDIOC_REQBUFS,\
    00075  * VIDIOC_STREAMON/VIDIOC_STREAMOFF, etc.
    00076  *
    00077  * The plane buffer type can be either V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE (for
    00078  * the output plane) or V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE (for the capture
    00079  * plane).
    00080  *
    00081  * The plane has an array of NvBuffer object pointers which is allocated and
    00082  * initialized during #reqbufs call. These NvBuffer objects are similar to the
    00083  * v4l2_buffer structures which are queued/dequeued.
    00084  *
    00085  * This class provides another feature useful for multi-threading. On calling
    00086  * #startDQThread, it internally spawns a thread which runs infinitely till
    00087  * signalled to stop. This thread keeps on trying to dequeue a buffer from the
    00088  * plane and calls a #dqThreadCallback function specified by the user on
    00089  * successful dequeue.
    00090  *
    00091  */
    00092 class NvV4l2ElementPlane
    00093 {
    00094
    00095 public:
    00096     /**
    00097      * Get the plane format
    00098      *
    00099      * Calls @b VIDIOC_G_FMT ioctl internally.
    00100      *
    00101      * @param[in,out] format Reference to v4l2_format structure to be filled
    00102      * @returns 0 for success, -1 for failure
    00103      */
    00104     int getFormat(struct v4l2_format & format);
    00105     /**
    00106      * Set the plane format
    00107      *
    00108      * Calls @b VIDIOC_S_FMT ioctl internally.
    00109      *
    00110      * @param[in] format Reference to v4l2_format structure to be set on the plane
    00111      * @returns 0 for success, -1 for failure
    00112      */
    00113     int setFormat(struct v4l2_format & format);
    00114
    00115     /**
    00116      * Get the cropping rectangle for the plane
    00117      *
    00118      * Calls @b VIDIOC_G_CROP ioctl internally.
    00119      *
    00120      * @param[in] crop Reference to v4l2_crop structure to be filled
    00121      * @returns 0 for success, -1 for failure
    00122      */
    00123     int getCrop(struct v4l2_crop & crop);
    00124
    00125     /**
    00126      * Set the selection rectangle for the plane
    00127      *
    00128      * Calls @b VIDIOC_S_SELECTION ioctl internally.
    00129      *
    00130      * @param[in] target Rectangle selection type
    00131      * @param[in] flags Flags to control selection adjustments
    00132      * @param[in] rect Selection rectangle
    00133      * @returns 0 for success, -1 for failure
    00134      */
    00135     int setSelection(uint32_t target, uint32_t flags, struct v4l2_rect & rect);
    00136
    00137     /**
    00138      * Request for buffers on the plane.
    00139      *
    00140      * Calls @b VIDIOC_REQBUFS ioctl internally. Creates an array of NvBuffer of
    00141      * length equal to the count returned by the ioctl.
    00142      *
    00143      * @param[in] mem_type Type of V4L2 Memory to be requested
    00144      * @param[in] num Number of buffers to request on the plane
    00145      * @returns 0 for success, -1 for failure
    00146      */
    00147     int reqbufs(enum v4l2_memory mem_type, uint32_t num);
    00148     /**
    00149      * Query the status of buffer at index
    00150      *
    00151      * @warning This functions works only for V4L2_MEMORY_MMAP memory.
    00152      *
    00153      * Calls VIDIOC_QUERYBUF ioctl internally. Populates the \a length and \a
    00154      * mem_offset members of all the NvBuffer::NvBufferPlane members of the
    00155      * NvBuffer object at index \a buf_index.
    00156      *
    00157      * @param[in] buf_index Index of the buffer to query
    00158      * @returns 0 for success, -1 for failure
    00159      */
    00160     int queryBuffer(uint32_t buf_index);
    00161     /**
    00162      * Export the buffer as DMABUF FD.
    00163      *
    00164      * @warning This functions works only for V4L2_MEMORY_MMAP memory.
    00165      *
    00166      * Calls VIDIOC_EXPBUF ioctl internally. Populates the \a fd member of all
    00167      * the NvBuffer::NvBufferPlane members of NvBuffer object at index \a buf_in.
    00168      *
    00169      * @param[in] buf_index Index of the buffer to export
    00170      * @returns 0 for success, -1 for failure
    00171      */
    00172     int exportBuffer(uint32_t buf_index);
    00173
    00174     /**
    00175      * Start or stop streaming on the plane.
    00176      *
    00177      * Calls VIDIOC_STREAMON/VIDIOC_STREAMOFF ioctls internally.
    00178      *
    00179      * @param[in] status Should be  true to start stream, false to stop stream
    00180      * @returns 0 for success, -1 for failure
    00181      */
    00182     int setStreamStatus(bool status);
    00183
    00184     /**
    00185      * Check if the plane is streaming.
    00186      *
    00187      * @returns true if the plane is streaming, false otherwise.
    00188      */
    00189     bool getStreamStatus();
    00190
    00191     /**
    00192      * Set streaming parameters.
    00193      *
    00194      * Calls VIDIOC_S_PARM ioctl internally.
    00195      *
    00196      * @param[in] parm Reference to v4l2_streamparm structure to be set on the
    00197      *                 plane
    00198      * @returns 0 for success, -1 for failure
    00199      */
    00200     int setStreamParms(struct v4l2_streamparm & parm);
    00201
    00202     /**
    00203      * Helper function which encapsulates all the function calls required to
    00204      * setup the plane for streaming.
    00205      *
    00206      * Calls #reqbufs internally. Then, for each of the buffers calls #queryBuffer,
    00207      * #exportBuffer and maps the buffer/allocates the buffer memory depending
    00208      * on the memory type.
    00209      *
    00210      * @sa deinitPlane
    00211      *
    00212      * @param[in] mem_type V4L2 Memory to use on the buffer
    00213      * @param[in] num_buffers Number of buffer to request on the plane
    00214      * @param[in] map boolean value indicating if the buffers should be mapped to
    00215                       memory (Only for V4L2_MEMORY_MMAP)
    00216      * @param[in] allocate boolean valued indicating if the buffers should be
    00217                            allocated memory (Only for V4L2_MEMORY_USERPTR)
    00218      * @returns 0 for success, -1 for failure
    00219      */
    00220     int setupPlane(enum v4l2_memory mem_type, uint32_t num_buffers, bool map, bool allocate);
    00221     /**
    00222      * Helper function which encapsulates all the function calls required to
    00223      * deinitialize the plane for streaming.
    00224      *
    00225      * For each of the buffers unmaps/deallocates memory depending on the
    00226      * memory type. Then, calls reqbufs with count zero.
    00227      *
    00228      * @sa setupPlane
    00229      */
    00230     void deinitPlane();
    00231
    00232     /**
    00233      * Get the streaming/buffer type of this plane.
    00234      *
    00235      * @returns Type of the buffer belonging to enum v4l2_buf_type
    00236      */
    00237     inline enum v4l2_buf_type getBufType()
    00238     {
    00239         return buf_type;
    00240     }
    00241
    00242     /**
    00243      * Get the NvBuffer object at index n
    00244      *
    00245      * @returns NvBuffer object at index n, NULL if n >= Number of buffers
    00246      */
    00247     NvBuffer *getNthBuffer(uint32_t n);
    00248
    00249     /**
    00250      * Dequeue a buffer from the plane.
    00251      *
    00252      * This is a blocking call. This call returns when a buffer is successfully
    00253      * dequeued or timeout is reached. If \a buffer is not NULL returns the
    00254      * NvBuffer object at the index returned by the VIDIOC_DQBUF ioctl. If this
    00255      * plane shares a buffer with other element and \a shared_buffer is not
    00256      * NULL returns the shared NvBuffer object in \a shared_buffer.
    00257      *
    00258      * @param[in] v4l2_buf v4l2_buffer structure to be used for dequeueing
    00259      * @param[out] buffer Returns the NvBuffer object associated with the dequeued
    00260      *                    buffer. Can be NULL
    00261      * @param[out] shared_buffer Returns the shared NvBuffer object, if the queued
    00262      *             buffer is being shared with other elements. Can be NULL.
    00263      * @param[in] num_retries Number of times to try dequeuing a buffer before
    00264      *                        a failure is returned. In case of non-blocking
    00265      *                        mode, this is equivalent to the number of
    00266      *                        milliseconds to try to dequeue a buffer.
    00267      * @returns 0 for success, -1 for failure/timeout
    00268      */
    00269     int dqBuffer(struct v4l2_buffer &v4l2_buf, NvBuffer ** buffer,
    00270                  NvBuffer ** shared_buffer, uint32_t num_retries);
    00271     /**
    00272      * Queue a buffer on the plane.
    00273      *
    00274      * This function calls VIDIOC_QBUF internally. If this plane is sharing
    00275      * buffer with other elements, the application can pass the pointer to the
    00276      * shared NvBuffer object in \a shared_buffer.
    00277      *
    00278      * @param[in] v4l2_buf v4l2_buffer structure to be used for queueing
    00279      * @param[in] shared_buffer Pointer to the shared NvBuffer object
    00280      * @returns 0 for success, -1 for failure/timeout
    00281      */
    00282     int qBuffer(struct v4l2_buffer &v4l2_buf, NvBuffer * shared_buffer);
    00283
    00284     /**
    00285      * Get the number of buffers allocated/requested on the plane
    00286      *
    00287      * @returns Number of buffers
    00288      */
    00289     inline uint32_t getNumBuffers()
    00290     {
    00291         return num_buffers;
    00292     }
    00293
    00294     /**
    00295      * Get the number of planes buffers on this plane contain for the currently
    00296      * set format
    00297      *
    00298      * @returns Number of planes
    00299      */
    00300     inline uint32_t getNumPlanes()
    00301     {
    00302         return n_planes;
    00303     }
    00304
    00305     /**
    00306      * Set the format of the planes of the buffer which will be used with this
    00307      * plane.
    00308      *
    00309      * The buffer plane format needs to be set before calling #reqbufs, since
    00310      * these are needed by the NvBuffer constructor.
    00311      *
    00312      * @sa reqbufs
    00313      *
    00314      * @param[in] n_planes Number of planes in the buffer
    00315      * @param[in] planefmts Array of NvBufferPlaneFormat which describes the
    00316      *            format of each of the plane. The array length should be at
    00317      *            least @a n_planes.
    00318      */
    00319     void setBufferPlaneFormat(int n_planes, NvBuffer::NvBufferPlaneFormat * planefmts);
    00320
    00321     /**
    00322      * Get the number of buffers currently queued on the plane
    00323      *
    00324      * @returns number of buffers  currently queued on the plane
    00325      */
    00326     inline uint32_t getNumQueuedBuffers()
    00327     {
    00328         return num_queued_buffers;
    00329     }
    00330
    00331     /**
    00332      * Get the total number of buffers dequeued from the plane
    00333      *
    00334      * @returns total number of buffers dequeued from the plane
    00335      */
    00336     inline uint32_t getTotalDequeuedBuffers()
    00337     {
    00338         return total_dequeued_buffers;
    00339     }
    00340
    00341     /**
    00342      * Get the total number of buffers queued on the plane
    00343      *
    00344      * @returns total number of buffers queued on the plane
    00345      */
    00346     inline uint32_t getTotalQueuedBuffers()
    00347     {
    00348         return total_queued_buffers;
    00349     }
    00350
    00351     /**
    00352      * Wait till all the buffers of the plane get queued
    00353      *
    00354      * This is a blocking call which returns when all the buffers get queued
    00355      * or timeout is reached.
    00356
    00357      * @param[in] max_wait_ms Maximum time to wait in milliseconds
    00358      * @returns 0 for success, -1 for failure/timeout
    00359      */
    00360     int waitAllBuffersQueued(uint32_t max_wait_ms);
    00361     /**
    00362      * Wait till all the buffers of the plane get dequeued
    00363      *
    00364      * This is a blocking call which returns when all the buffers get dequeued
    00365      * or timeout is reached.
    00366
    00367      * @param[in] max_wait_ms Maximum time to wait in milliseconds
    00368      * @returns 0 for success, -1 for failure/timeout
    00369      */
    00370     int waitAllBuffersDequeued(uint32_t max_wait_ms);
    00371
    00372     /**
    00373      * This is a callback function type which is called by the DQ Thread when
    00374      * it successfully dequeues a buffer from the plane. Applications must implement
    00375      * this and set the callback using #setDQThreadCallback.
    00376      *
    00377      * Setting the stream to off will automatically stop this thread.
    00378      *
    00379      * @sa setDQThreadCallback, #startDQThread
    00380      *
    00381      * @param v4l2_buf v4l2_buffer structure which was used for dequeueing
    00382      * @param buffer NvBuffer object at the @a index contained in @a v4l2_buf
    00383      * @param shared_buffer If the plane shares buffer with another elements
    00384      *         pointer to the NvBuffer object else NULL
    00385      * @param data Pointer to application specific data which was set with
    00386      *             #startDQThread
    00387      * @returns If the application implementing this calls returns false,
    00388      *          the DQThread will be stopped else the DQThread will continue running.
    00389      */
    00390     typedef bool(*dqThreadCallback) (struct v4l2_buffer * v4l2_buf,
    00391             NvBuffer * buffer, NvBuffer * shared_buffer,
    00392             void *data);
    00393
    00394     /**
    00395      * Set the DQ Thread callback function.
    00396      *
    00397      * The callback function is called from the DQ Thread once a buffer is
    00398      * successfully dequeued.
    00399
    00400      * @param[in] callback Function to be called on succesful dequeue
    00401      * @returns true for success, false for failure
    00402      */
    00403     bool setDQThreadCallback(dqThreadCallback callback);
    00404     /**
    00405      * Start DQ Thread.
    00406      *
    00407      * This function starts a thread internally. On successful dequeue of a
    00408      * buffer from the plane, #dqThreadCallback function set using
    00409      * setDQThreadCallback gets called.
    00410      *
    00411      * Setting the stream to off will automatically stop the thread.
    00412      *
    00413      * @sa stopDQThread, waitForDQThread
    00414      *
    00415      * @param[in] data Application data pointer. This is provided as an
    00416      *                 argument in the dqThreadCallback function
    00417      * @returns 0 for success, -1 for failure/timeout
    00418      */
    00419     int startDQThread(void *data);
    00420     /**
    00421      * Force stop the DQ Thread if it is running.
    00422      *
    00423      * Does not work when the device has been opened in blocking mode.
    00424      *
    00425      * @sa startDQThread, waitForDQThread
    00426      *
    00427      * @returns 0 for success, -1 for failure/timeout
    00428      */
    00429     int stopDQThread();
    00430     /**
    00431      * Wait for the DQ Thread to stop
    00432      *
    00433      * This function waits till the DQ Thread stops or timeout is reached
    00434      *
    00435      * @sa startDQThread, stopDQThread
    00436      *
    00437      * @param[in] max_wait_ms
    00438      * @returns 0 for success, -1 for failure/timeout
    00439      */
    00440     int waitForDQThread(uint32_t max_wait_ms);
    00441
    00442     pthread_mutex_t plane_lock; /**< Mutex lock used along with #plane_cond */
    00443     pthread_cond_t plane_cond; /**< Plane condition which application can wait on
    00444                                     to receive notifications from
    00445                                     #qBuffer/#dqBuffer */
    00446
    00447 private:
    00448     int &fd;     /**< FD of the V4l2 Element the plane is associated with */
    00449
    00450     const char *plane_name; /**< Name of the plane. Could be "Output Plane" or
    00451                                  "Capture Plane". Used only for debug logs */
    00452
    00453     enum v4l2_buf_type buf_type; /**< Type of the stream. */
    00454
    00455     bool blocking;  /**< Whether the V4l2 element has been opened with
    00456                          blocking mode */
    00457
    00458     uint32_t num_buffers;   /**< Number of buffers returned by VIDIOC_REQBUFS
    00459                                  ioctl */
    00460     NvBuffer **buffers;     /**< Array of NvBuffer object pointers. This array is
    00461                                  allocated and initialized in #reqbufs. */
    00462
    00463     uint8_t n_planes;       /**< Number of planes in the buffers */
    00464     NvBuffer::NvBufferPlaneFormat planefmts[MAX_PLANES];
    00465                             /**< Format of the buffer planes. This should be
    00466                                  initialized before calling #reqbufs since this
    00467                                  is required by the NvBuffer constructor */
    00468
    00469     enum v4l2_memory memory_type; /**< V4l2 memory type of the buffers */
    00470
    00471     uint32_t num_queued_buffers;  /**< Number of buffers currently queued on the
    00472                                        plane */
    00473     uint32_t total_queued_buffers;  /**< Total number of buffers queued on the
    00474                                          plane */
    00475     uint32_t total_dequeued_buffers;  /**< Total number of buffers dequeued from
    00476                                            the plane */
    00477
    00478     bool streamon;  /**< Boolean indicating if the plane is streaming */
    00479
    00480     bool dqthread_running;  /**< Boolean indicating if the DQ Thread is running.
    00481                                  Its value is toggled by the DQ Thread */
    00482     bool stop_dqthread; /**< Boolean value used to signal the DQ Thread to stop */
    00483
    00484     pthread_t dq_thread; /**< pthread ID of the DQ Thread */
    00485
    00486     dqThreadCallback callback; /**< Callback function used by the DQ Thread */
    00487
    00488     void *dqThread_data;    /**< Application supplied pointer provided as an
    00489                                 argument in #dqThreadCallback */
    00490
    00491     /**
    00492      * The DQ thread function.
    00493      *
    00494      * This function keeps on running infinitely till it is signalled to stop
    00495      * by #stopDQThread or the #dqThreadCallback function returns false.
    00496      * It keeps on trying to dequeue a buffer from the plane and calls the
    00497      * #dqThreadCallback function on successful dequeue
    00498      *
    00499      * @param[in] v4l2_element_plane Pointer to the NvV4l2ElementPlane object
    00500      *                 for which the thread has been started
    00501      */
    00502     static void *dqThread(void *v4l2_element_plane);
    00503
    00504     NvElementProfiler &v4l2elem_profiler; /**< A reference to the profiler belonging
    00505                                             to the plane's parent element. */
    00506
    00507     /**
    00508      * Indicates if the plane encountered an error during its operation.
    00509      *
    00510      * @return 0 if no error was encountered, a non-zero value if an
    00511      *            error was encountered.
    00512      */
    00513     inline int isInError()
    00514     {
    00515         return is_in_error;
    00516     }
    00517
    00518     /**
    00519      * Creates a new V4l2Element plane
    00520      *
    00521      *
    00522      * @param[in] buf_type Type of the stream
    00523      * @param[in] device_name Name of the element the plane belongs to
    00524      * @param[in] fd FD of the device opened using v4l2_open
    00525      * @param[in] blocking Whether the device has been opened with blocking mode
    00526      */
    00527     NvV4l2ElementPlane(enum v4l2_buf_type buf_type, const char *device_name,
    00528                      int &fd, bool blocking, NvElementProfiler &profiler);
    00529
    00530     /**
    00531      * Disallow copy constructor.
    00532      */
    00533     NvV4l2ElementPlane(const NvV4l2ElementPlane& that);
    00534     /**
    00535      * Disallow assignment.
    00536      */
    00537     void operator=(NvV4l2ElementPlane const&);
    00538
    00539     /**
    00540      * NvV4l2ElementPlane destructor.
    00541      *
    00542      * Calls #deinitPlane internally.
    00543      */
    00544      ~NvV4l2ElementPlane();
    00545
    00546     int is_in_error;        /**< Indicates if an error was encountered during
    00547                                the operation of the element. */
    00548     const char *comp_name;  /**< Specifies the name of the component,
    00549                                for debugging. */
    00550
    00551     friend class NvV4l2Element;
    00552 };
    00553
    00554 #endif