cpp-callback-2.cpp
Go to the documentation of this file.
00001 // License: Apache 2.0. See LICENSE file in root directory.
00002 // Copyright(c) 2015 Intel Corporation. All Rights Reserved.
00003 
00005 // librealsense Multi-threading Demo 3 - callbacks                                  //
00007 
00008 #include <librealsense/rs.hpp>
00009 #include <cstdio>
00010 #include <atomic>
00011 #include <map>
00012 #include <GLFW/glfw3.h>
00013 
00014 #include "concurrency.hpp"
00015 #include "example.hpp"
00016 
00017 int main() try
00018 {
00019     rs::context ctx;
00020     printf("There are %d connected RealSense devices.\n", ctx.get_device_count());
00021     if (ctx.get_device_count() == 0) return EXIT_FAILURE;
00022 
00023     rs::device * dev = ctx.get_device(0);
00024     printf("\nUsing device 0, an %s\n", dev->get_name());
00025     printf("    Serial number: %s\n", dev->get_serial());
00026     printf("    Firmware version: %s\n", dev->get_firmware_version());
00027 
00028     const auto streams = 4;
00029     single_consumer_queue<rs::frame> frames_queue[streams];
00030     texture_buffer buffers[streams];
00031     std::atomic<bool> running(true);
00032 
00033     struct resolution
00034     {
00035         int width;
00036         int height;
00037         rs::format format;
00038     };
00039     std::map<rs::stream, resolution> resolutions;
00040 
00041     for (auto i = 0; i < streams; i++)
00042     {
00043         // Set callback to be executed when frame of stream i is ready
00044         dev->set_frame_callback((rs::stream)i, [dev, &running, &frames_queue, &resolutions, i](rs::frame frame)
00045         {
00046             if (running) frames_queue[i].enqueue(std::move(frame)); 
00047             // Important: Not constraining the max size of the queue will prevent frames from being dropped at the expense of lattency
00048         });
00049     }
00050 
00051     dev->enable_stream(rs::stream::depth, 0, 0, rs::format::z16, 60);
00052     dev->enable_stream(rs::stream::color, 640, 480, rs::format::rgb8, 60);
00053     dev->enable_stream(rs::stream::infrared, 0, 0, rs::format::y8, 60);
00054     if (dev->supports(rs::capabilities::infrared2))
00055     {
00056         dev->enable_stream(rs::stream::infrared2, 0, 0, rs::format::y8, 60);
00057     }
00058 
00059     resolutions[rs::stream::depth] = { dev->get_stream_width(rs::stream::depth), dev->get_stream_height(rs::stream::depth), rs::format::z16 };
00060     resolutions[rs::stream::color] = { dev->get_stream_width(rs::stream::color), dev->get_stream_height(rs::stream::color), rs::format::rgb8 };
00061     resolutions[rs::stream::infrared] = { dev->get_stream_width(rs::stream::infrared), dev->get_stream_height(rs::stream::infrared), rs::format::y8 };
00062     if (dev->is_stream_enabled(rs::stream::infrared2))
00063         resolutions[rs::stream::infrared2] = { dev->get_stream_width(rs::stream::infrared2), dev->get_stream_height(rs::stream::infrared2), rs::format::y8 };
00064 
00065     glfwInit();
00066 
00067     auto max_aspect_ratio = 0.0f;
00068     for (auto i = 0; i < streams; i++)
00069     {
00070         auto aspect_ratio = static_cast<float>(resolutions[static_cast<rs::stream>(i)].height) / static_cast<float>(resolutions[static_cast<rs::stream>(i)].width);
00071         if (max_aspect_ratio < aspect_ratio)
00072             max_aspect_ratio = aspect_ratio;
00073     };
00074 
00075     auto win = glfwCreateWindow(1100, int(1100 * max_aspect_ratio), "librealsense - callback 2", nullptr, nullptr);
00076     glfwMakeContextCurrent(win);
00077 
00078     dev->start();
00079 
00080     while (!glfwWindowShouldClose(win))
00081     {
00082         glfwPollEvents();
00083         rs::frame frame;
00084 
00085         int w, h;
00086         glfwGetFramebufferSize(win, &w, &h);
00087         glViewport(0, 0, w, h);
00088         glClear(GL_COLOR_BUFFER_BIT);
00089 
00090         glfwGetWindowSize(win, &w, &h);
00091         glLoadIdentity();
00092         glOrtho(0, w, h, 0, -1, +1);
00093 
00094         for (auto i = 0; i < streams; i++)
00095         {
00096             auto res = resolutions[(rs::stream)i];
00097 
00098             if (frames_queue[i].try_dequeue(&frame)) // If new frame of stream i is available
00099             {
00100                 buffers[i].upload(frame.get_data(), res.width, res.height, res.format); // Update the texture
00101             }
00102 
00103             auto x = (i % 2) * (w / 2);
00104             auto y = (i / 2) * (h / 2);
00105             buffers[i].show(x, y, w / 2, h / 2, res.width, res.height);
00106         }
00107 
00108         glfwSwapBuffers(win);
00109     }
00110 
00111     running = false;
00112 
00113     for (auto i = 0; i < streams; i++) frames_queue[i].clear();
00114 
00115     dev->stop();
00116 
00117     for (auto i = 0; i < streams; i++)
00118     {
00119         if (dev->is_stream_enabled((rs::stream)i))
00120             dev->disable_stream((rs::stream)i);
00121     }
00122 
00123     return EXIT_SUCCESS;
00124 }
00125 catch (const rs::error & e)
00126 {
00127     printf("rs::error was thrown when calling %s(%s):\n", e.get_failed_function().c_str(), e.get_failed_args().c_str());
00128     printf("    %s\n", e.what());
00129     return EXIT_FAILURE;
00130 }


librealsense
Author(s): Sergey Dorodnicov , Mark Horn , Reagan Lopez
autogenerated on Tue Jun 25 2019 19:54:38