Argus Camera Sample Argus Camera Sample

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
StreamConsumer.cpp
Go to the documentation of this file.
1 /*
2 * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of NVIDIA CORPORATION nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #define GL_GLEXT_PROTOTYPES
30
31 #include <GLES3/gl31.h>
32 #include <GLES2/gl2ext.h>
33
34 #include <unistd.h>
35
36 #include "StreamConsumer.h"
37 #include "Composer.h"
38 #include "Error.h"
39 #include "Util.h" // for TimeValue
40
41 namespace ArgusSamples
42 {
43
44 StreamConsumer::StreamConsumer(EGLStreamKHR eglStream)
45 : m_initialized(false)
46 , m_eglStream(eglStream)
47 , m_streamState(EGL_NONE)
48 , m_streamTexture(0)
49 , m_aspectRatio(1.0f)
50 {
51 }
52
53 StreamConsumer::~StreamConsumer()
54 {
55 if (!shutdown())
56 REPORT_ERROR("Failed to shutdown stream consumer");
57 }
58
59 bool StreamConsumer::initialize()
60 {
61 if (m_initialized)
62 return true;
63
64 // Create an external texture and connect it to the stream as a the consumer.
65 glGenTextures(1, &m_streamTexture);
66 if (m_streamTexture == 0)
67 ORIGINATE_ERROR("Failed to create GL texture");
68
69 glBindTexture(GL_TEXTURE_EXTERNAL_OES, m_streamTexture);
70 if (!eglStreamConsumerGLTextureExternalKHR(Composer::getInstance().getEGLDisplay(),
71 m_eglStream))
72 {
73 ORIGINATE_ERROR("Unable to connect GL as consumer");
74 }
75 glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
76
77 m_initialized = true;
78
79 return true;
80 }
81
82 bool StreamConsumer::shutdown()
83 {
84 if (m_streamTexture)
85 {
86 glDeleteTextures(1, &m_streamTexture);
87 m_streamTexture = 0;
88 }
89
90 m_initialized = false;
91
92 return true;
93 }
94
95 bool StreamConsumer::isEGLStream(EGLStreamKHR eglStream) const
96 {
97 return (m_eglStream == eglStream);
98 }
99
100 uint32_t StreamConsumer::getStreamTextureID() const
101 {
102 return m_streamTexture;
103 }
104
105 bool StreamConsumer::setStreamAspectRatio(float aspectRatio)
106 {
107 m_aspectRatio = aspectRatio;
108 return true;
109 }
110
111 float StreamConsumer::getStreamAspectRatio() const
112 {
113 return m_aspectRatio;
114 }
115
116 bool StreamConsumer::acquire(bool *acquiredNewFrame)
117 {
118 if (!m_initialized)
119 PROPAGATE_ERROR(initialize());
120
121 const EGLDisplay display = Composer::getInstance().getEGLDisplay();
122
123 // check the stream state
124 if (!eglQueryStreamKHR(display, m_eglStream, EGL_STREAM_STATE_KHR, &m_streamState))
125 ORIGINATE_ERROR("eglQueryStreamKHR failed (error 0x%04x)", eglGetError());
126
127 if ((m_streamState == EGL_BAD_STREAM_KHR) ||
128 (m_streamState == EGL_BAD_STATE_KHR))
129 {
130 ORIGINATE_ERROR("EGL stream is in bad state (0x%04x)", m_streamState);
131 }
132 else if (m_streamState == EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR)
133 {
134 // acquire the new frame
135 if (!eglStreamConsumerAcquireKHR(display, m_eglStream))
136 {
137 // if the acquire failed check if the stream had been disconnected
138 const EGLint eglError = eglGetError();
139 if (eglError == EGL_BAD_STATE_KHR)
140 m_streamState = EGL_BAD_STATE_KHR;
141 else
142 ORIGINATE_ERROR("Failed to acquire from egl stream (error 0x%04x)", eglError);
143 }
144 else
145 {
146 if (acquiredNewFrame)
147 *acquiredNewFrame = true;
148 }
149 }
150 else if ((m_streamState == EGL_NONE) ||
151 (m_streamState == EGL_STREAM_STATE_CONNECTING_KHR))
152 {
153 // if the producer is not yet connected just return
154 }
155 else if ((m_streamState == EGL_STREAM_STATE_EMPTY_KHR) ||
156 (m_streamState == EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR))
157 {
158 // no frame or no new frame, nothing to do
159 }
160 else if (m_streamState == EGL_STREAM_STATE_DISCONNECTED_KHR)
161 {
162 // producer had been disconnected, ignore
163 }
164 else
165 {
166 ORIGINATE_ERROR("Unhandled EGL stream state (0x%04x)", m_streamState);
167 }
168
169 return true;
170 }
171
172 }; // namespace ArgusSamples