summaryrefslogtreecommitdiff
path: root/Documentation
AgeCommit message (Expand)Author
2021-02-16libcamera: IPAInterface: Replace C API with the new C++-only APIPaul Elder
2021-02-16libcamera: Add IPCPipe implementation based on unix socketPaul Elder
2021-02-16Documentation: skip generating documentation for generated codePaul Elder
2021-02-05libcamera: camera_sensor: Restrict sensor info to raw sensorsLaurent Pinchart
2021-02-05libcamera: camera_sensor: Make VBLANK mandatoryJacopo Mondi
2021-01-25libcamera: camera_sensor: Make V4L2_CID_EXPOSURE mandatoryJacopo Mondi
2021-01-20Documentation: sensor-driver: Correct camera rotationJacopo Mondi
2021-01-20Documentation: sensor-drivers: Reorder introductionJacopo Mondi
2021-01-18libcamera: Document sensor driver requirementsJacopo Mondi
2020-12-29utils: checkstyle.py: Drop astyle supportLaurent Pinchart
2020-12-28libcamera: pipeline_handler: Remove Camera argument from request handlingNiklas Söderlund
2020-12-27Documentation: Fix Doxygen exclusion of details namespacesLaurent Pinchart
2020-12-27Documentation: Restore alphabetical order of sources in meson.buildLaurent Pinchart
2020-12-27Documentation: Add descriptions for environment variablesSebastian Fricke
2020-12-27Documentation: Drop deprecated Doxygen COLS_IN_ALPHA_INDEX optionLaurent Pinchart
2020-12-08libcamera: pipeline: Pass libcamera controls into pipeline_handler::start()Naushir Patuck
2020-12-01Documentation: Fix doxygen warningLaurent Pinchart
2020-11-03Documentation: tracing: Add tracing guidePaul Elder
2020-11-03libcamera: tracing: Implement tracing infrastructurePaul Elder
2020-10-26Documentation: Fix typo in pipeline handler guideSebastian Fricke
2020-10-20libcamera: Omit extra semicolonsHirokazu Honda
2020-10-07Documentation: coding-style: Document global variable guidelinesPaul Elder
2020-09-30Documentation: guides: pipeline-handler: Update clamp() namespaceUmang Jain
2020-09-24Documentation: Move all dependencies into featuresRicardo Ribalda
2020-09-24Documentation: Search for dot binaryRicardo Ribalda
2020-09-21Documentation: Adjust guidelines regarding math.h headerLaurent Pinchart
2020-08-25meson: Switch to C++17Laurent Pinchart
2020-08-20Documentation: Guides: Pipeline Handler Writer's GuideChris Chinchilla
2020-08-20Documentation: Guides: Application Writer's GuideChris Chinchilla
2020-08-20Documentation: Guides: Developer's Guide to libcameraChris Chinchilla
2020-06-16Documentation: Drop TCL_SUBST tag from Doxyfile.inLaurent Pinchart
2020-06-09licenses: Add SPDX headers to the website builder and themeLaurent Pinchart
2020-06-05docs: Markup LD_PRELOAD as codeMarvin Schmidt
2020-06-05docs: coding-style: Change full stop to colonMarvin Schmidt
2020-06-05docs: Remove trailing whitespaceMarvin Schmidt
2020-06-05docs: Remove stray HTML tagsMarvin Schmidt
2020-05-18meson: Rename variables storing headers listsLaurent Pinchart
2020-05-16libcamera: Move IPA headers from include/ipa/ to include/libcamera/ipa/Laurent Pinchart
2020-05-16libcamera: Move internal headers to include/libcamera/internal/Laurent Pinchart
2020-05-13licenses: License all meson files under CC0-1.0Laurent Pinchart
2020-05-11Documentation: coding-style: Fix ordered listsLaurent Pinchart
2020-04-15licenses: Add SPDX headers to Doxygen configurationLaurent Pinchart
2020-04-15licenses: Add SPDX headers to RST documentationLaurent Pinchart
2020-04-15licenses: Move developer's certificate of origin to Documentation/Laurent Pinchart
2020-03-06libcamera: controls: Add templates to convert a type T to a ControlTypeLaurent Pinchart
2020-03-06libcamera: Add a C++20-compliant std::span<> implementationJacopo Mondi
2020-02-13libcamera: utils: Add string splitter utility functionLaurent Pinchart
2020-02-13libcamera: Define the threading modelLaurent Pinchart
2020-01-31Documentation: Add linkcheck targetKieran Bingham
2020-01-23libcamera: camera_manager: Move private data members to private implementationLaurent Pinchart
b = eglInitialize(dpy, major, minor) assert(b) print('EGL {} {}'.format( eglQueryString(dpy, EGL_VENDOR).decode(), eglQueryString(dpy, EGL_VERSION).decode())) check_egl_extensions(dpy, ['EGL_EXT_image_dma_buf_import']) b = eglBindAPI(EGL_OPENGL_ES_API) assert(b) def print_config(dpy, cfg): def getconf(a): value = ctypes.c_long() eglGetConfigAttrib(dpy, cfg, a, value) return value.value print('EGL Config {}: color buf {}/{}/{}/{} = {}, depth {}, stencil {}, native visualid {}, native visualtype {}'.format( getconf(EGL_CONFIG_ID), getconf(EGL_ALPHA_SIZE), getconf(EGL_RED_SIZE), getconf(EGL_GREEN_SIZE), getconf(EGL_BLUE_SIZE), getconf(EGL_BUFFER_SIZE), getconf(EGL_DEPTH_SIZE), getconf(EGL_STENCIL_SIZE), getconf(EGL_NATIVE_VISUAL_ID), getconf(EGL_NATIVE_VISUAL_TYPE))) if False: num_configs = ctypes.c_long() eglGetConfigs(dpy, None, 0, num_configs) print('{} configs'.format(num_configs.value)) configs = (EGLConfig * num_configs.value)() eglGetConfigs(dpy, configs, num_configs.value, num_configs) for config_id in configs: print_config(dpy, config_id) config_attribs = [ EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 0, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE, ] n = EGLint() configs = (EGLConfig * 1)() b = eglChooseConfig(dpy, config_attribs, configs, 1, n) assert(b and n.value == 1) config = configs[0] print('Chosen Config:') print_config(dpy, config) self.config = config def create_context(self): dpy = self.display context_attribs = [ EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, ] context = eglCreateContext(dpy, self.config, EGL_NO_CONTEXT, context_attribs) assert(context) b = eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, context) assert(b) self.context = context def check_extensions(self): check_gl_extensions(['GL_OES_EGL_image']) assert(eglCreateImageKHR) assert(eglDestroyImageKHR) assert(glEGLImageTargetTexture2DOES) class QtRenderer: def __init__(self, state): self.state = state def setup(self): self.app = QtWidgets.QApplication([]) window = MainWindow(self.state) window.setAttribute(QtCore.Qt.WA_ShowWithoutActivating) window.show() self.window = window def run(self): camnotif = QtCore.QSocketNotifier(self.state['cm'].efd, QtCore.QSocketNotifier.Read) camnotif.activated.connect(lambda x: self.readcam()) keynotif = QtCore.QSocketNotifier(sys.stdin.fileno(), QtCore.QSocketNotifier.Read) keynotif.activated.connect(lambda x: self.readkey()) print('Capturing...') self.app.exec() print('Exiting...') def readcam(self): running = self.state['event_handler'](self.state) if not running: self.app.quit() def readkey(self): sys.stdin.readline() self.app.quit() def request_handler(self, ctx, req): self.window.handle_request(ctx, req) def cleanup(self): self.window.close() class MainWindow(QtWidgets.QWidget): def __init__(self, state): super().__init__() self.setAttribute(Qt.WA_PaintOnScreen) self.setAttribute(Qt.WA_NativeWindow) self.state = state self.textures = {} self.reqqueue = {} self.current = {} for ctx in self.state['contexts']: self.reqqueue[ctx['idx']] = [] self.current[ctx['idx']] = [] for stream in ctx['streams']: self.textures[stream] = None num_tiles = len(self.textures) self.num_columns = math.ceil(math.sqrt(num_tiles)) self.num_rows = math.ceil(num_tiles / self.num_columns) self.egl = EglState() self.surface = None def paintEngine(self): return None def create_surface(self): native_surface = c_void_p(self.winId().__int__()) surface = eglCreateWindowSurface(self.egl.display, self.egl.config, native_surface, None) b = eglMakeCurrent(self.egl.display, self.surface, self.surface, self.egl.context) assert(b) self.surface = surface def init_gl(self): self.create_surface() vertShaderSrc = ''' attribute vec2 aPosition; varying vec2 texcoord; void main() { gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0); texcoord.x = aPosition.x; texcoord.y = 1.0 - aPosition.y; } ''' fragShaderSrc = ''' #extension GL_OES_EGL_image_external : enable precision mediump float; varying vec2 texcoord; uniform samplerExternalOES texture; void main() { gl_FragColor = texture2D(texture, texcoord); } ''' program = shaders.compileProgram( shaders.compileShader(vertShaderSrc, GL_VERTEX_SHADER), shaders.compileShader(fragShaderSrc, GL_FRAGMENT_SHADER) ) glUseProgram(program) glClearColor(0.5, 0.8, 0.7, 1.0) vertPositions = [ 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0 ] inputAttrib = glGetAttribLocation(program, 'aPosition') glVertexAttribPointer(inputAttrib, 2, GL_FLOAT, GL_FALSE, 0, vertPositions) glEnableVertexAttribArray(inputAttrib) def create_texture(self, stream, fb): cfg = stream.configuration fmt = cfg.pixel_format.fourcc w = cfg.size.width h = cfg.size.height attribs = [ EGL_WIDTH, w, EGL_HEIGHT, h, EGL_LINUX_DRM_FOURCC_EXT, fmt, EGL_DMA_BUF_PLANE0_FD_EXT, fb.fd(0), EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, EGL_DMA_BUF_PLANE0_PITCH_EXT, cfg.stride, EGL_NONE, ] image = eglCreateImageKHR(self.egl.display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, None, attribs) assert(image) textures = glGenTextures(1) glBindTexture(GL_TEXTURE_EXTERNAL_OES, textures) glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image) return textures def resizeEvent(self, event): size = event.size() print('Resize', size) super().resizeEvent(event) if self.surface is None: return glViewport(0, 0, size.width() // 2, size.height()) def paintEvent(self, event): if self.surface is None: self.init_gl() for ctx_idx, queue in self.reqqueue.items(): if len(queue) == 0: continue ctx = next(ctx for ctx in self.state['contexts'] if ctx['idx'] == ctx_idx) if self.current[ctx_idx]: old = self.current[ctx_idx] self.current[ctx_idx] = None self.state['request_prcessed'](ctx, old) next_req = queue.pop(0) self.current[ctx_idx] = next_req stream, fb = next(iter(next_req.buffers.items())) self.textures[stream] = self.create_texture(stream, fb) self.paint_gl() def paint_gl(self): b = eglMakeCurrent(self.egl.display, self.surface, self.surface, self.egl.context) assert(b) glClear(GL_COLOR_BUFFER_BIT) size = self.size() for idx, ctx in enumerate(self.state['contexts']): for stream in ctx['streams']: if self.textures[stream] is None: continue w = size.width() // self.num_columns h = size.height() // self.num_rows x = idx % self.num_columns y = idx // self.num_columns x *= w y *= h glViewport(x, y, w, h) glBindTexture(GL_TEXTURE_EXTERNAL_OES, self.textures[stream]) glDrawArrays(GL_TRIANGLE_FAN, 0, 4) b = eglSwapBuffers(self.egl.display, self.surface) assert(b) def handle_request(self, ctx, req): self.reqqueue[ctx['idx']].append(req) self.update()