/* * 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. */ #include "Error.h" #include "Thread.h" #include #include #include #include #include #include #include "NvUtils.h" #include #include #include #include #include #include using namespace Argus; using namespace EGLStream; // Constant configuration. static const uint32_t CAPTURE_TIME = 1; // In seconds. static const int DEFAULT_FPS = 30; // Configurations which can be overrided by cmdline static Size PREVIEW_SIZE (640, 480); static Size CAPTURE_SIZE (1920, 1080); static bool DO_STAT = false; static bool VERBOSE_ENABLE = false; #define DO_CAPTURE 0 #define DUMP2FILE 1 #define JPEG_BUFFER_SIZE (CAPTURE_SIZE.width * CAPTURE_SIZE.height * 3 / 2) // Debug print macros. #define PRODUCER_PRINT(...) printf("PRODUCER: " __VA_ARGS__) #define CONSUMER_PRINT(...) printf("CONSUMER: " __VA_ARGS__) namespace ArgusSamples { /******************************************************************************* * Base Consumer thread: * Creates an EGLStream::FrameConsumer object to read frames from the * OutputStream, then creates/populates an NvBuffer (dmabuf) from the frames * to be processed by processV4L2Fd. ******************************************************************************/ class ConsumerThread : public Thread { public: explicit ConsumerThread(OutputStream* stream) : m_stream(stream), m_dmabuf(-1) { } virtual ~ConsumerThread(); protected: /** @name Thread methods */ /**@{*/ virtual bool threadInitialize(); virtual bool threadExecute(); virtual bool threadShutdown(); /**@}*/ virtual bool processV4L2Fd(int32_t fd, uint64_t frameNumber) = 0; OutputStream* m_stream; UniqueObj m_consumer; int m_dmabuf; }; ConsumerThread::~ConsumerThread() { if (m_dmabuf != -1) NvBufferDestroy(m_dmabuf); } bool ConsumerThread::threadInitialize() { // Create the FrameConsumer. m_consumer = UniqueObj(FrameConsumer::create(m_stream)); if (!m_consumer) ORIGINATE_ERROR("Failed to create FrameConsumer"); return true; } bool ConsumerThread::threadExecute() { IStream *iStream = interface_cast(m_stream); IFrameConsumer *iFrameConsumer = interface_cast(m_consumer); // Wait until the producer has connected to the stream. CONSUMER_PRINT("Waiting until producer is connected...\n"); if (iStream->waitUntilConnected() != STATUS_OK) ORIGINATE_ERROR("Stream failed to connect."); CONSUMER_PRINT("Producer has connected; continuing.\n"); while (true) { // Acquire a frame. UniqueObj frame(iFrameConsumer->acquireFrame()); IFrame *iFrame = interface_cast