Argus Camera Sample
Argus Camera Sample
 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 
54 {
55  if (!shutdown())
56  REPORT_ERROR("Failed to shutdown stream consumer");
57 }
58 
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 
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 
101 {
102  return m_streamTexture;
103 }
104 
106 {
107  m_aspectRatio = aspectRatio;
108  return true;
109 }
110 
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