types.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 
00004 #include "types.h"
00005 #include "image.h"
00006 #include "device.h"
00007 
00008 #include <cstring>
00009 #include <algorithm>
00010 #include <array>
00011 #include <deque>
00012 #include <algorithm>
00013 #include <iomanip>
00014 
00015 #define unknown "UNKNOWN" 
00016 
00017 namespace rsimpl
00018 {
00019     const char * get_string(rs_stream value)
00020     {
00021         #define CASE(X) case RS_STREAM_##X: return #X;
00022         switch(value)
00023         {
00024         CASE(DEPTH)
00025         CASE(COLOR)
00026         CASE(INFRARED)
00027         CASE(INFRARED2)
00028         CASE(POINTS)
00029         CASE(RECTIFIED_COLOR)
00030         CASE(COLOR_ALIGNED_TO_DEPTH)
00031         CASE(DEPTH_ALIGNED_TO_COLOR)
00032         CASE(DEPTH_ALIGNED_TO_RECTIFIED_COLOR)
00033         CASE(INFRARED2_ALIGNED_TO_DEPTH)
00034         CASE(DEPTH_ALIGNED_TO_INFRARED2)
00035         CASE(FISHEYE)
00036         default: assert(!is_valid(value)); return unknown;
00037         }
00038         #undef CASE
00039     }
00040 
00041     const char * get_string(rs_format value)
00042     {
00043         #define CASE(X) case RS_FORMAT_##X: return #X;
00044         switch(value)
00045         {
00046         CASE(ANY)
00047         CASE(Z16)
00048         CASE(DISPARITY16)
00049         CASE(XYZ32F)
00050         CASE(YUYV)
00051         CASE(RGB8)
00052         CASE(BGR8)
00053         CASE(RGBA8)
00054         CASE(BGRA8)
00055         CASE(Y8)
00056         CASE(Y16)
00057         CASE(RAW10)
00058         CASE(RAW16)
00059         CASE(RAW8)
00060         default: assert(!is_valid(value)); return unknown;
00061         }
00062         #undef CASE
00063     }
00064 
00065     const char * get_string(rs_preset value)
00066     {
00067         #define CASE(X) case RS_PRESET_##X: return #X;
00068         switch(value)
00069         {
00070         CASE(BEST_QUALITY)
00071         CASE(LARGEST_IMAGE)
00072         CASE(HIGHEST_FRAMERATE)
00073         default: assert(!is_valid(value)); return unknown;
00074         }
00075         #undef CASE
00076     }
00077 
00078     const char * get_string(rs_distortion value)
00079     {
00080         #define CASE(X) case RS_DISTORTION_##X: return #X;
00081         switch(value)
00082         {
00083         CASE(NONE)
00084         CASE(MODIFIED_BROWN_CONRADY)
00085         CASE(INVERSE_BROWN_CONRADY)
00086         CASE(FTHETA)
00087         default: assert(!is_valid(value)); return unknown;
00088         }
00089         #undef CASE
00090     }
00091 
00092     const char * get_string(rs_option value)
00093     {
00094         #define CASE(X) case RS_OPTION_##X: return #X;
00095         switch(value)
00096         {
00097         CASE(COLOR_BACKLIGHT_COMPENSATION)
00098         CASE(COLOR_BRIGHTNESS)
00099         CASE(COLOR_CONTRAST)
00100         CASE(COLOR_EXPOSURE)
00101         CASE(COLOR_GAIN)
00102         CASE(COLOR_GAMMA)
00103         CASE(COLOR_HUE)
00104         CASE(COLOR_SATURATION)
00105         CASE(COLOR_SHARPNESS)
00106         CASE(COLOR_WHITE_BALANCE)
00107         CASE(COLOR_ENABLE_AUTO_EXPOSURE)
00108         CASE(COLOR_ENABLE_AUTO_WHITE_BALANCE)
00109         CASE(F200_LASER_POWER)
00110         CASE(F200_ACCURACY)
00111         CASE(F200_MOTION_RANGE)
00112         CASE(F200_FILTER_OPTION)
00113         CASE(F200_CONFIDENCE_THRESHOLD)
00114         CASE(F200_DYNAMIC_FPS)
00115         CASE(SR300_AUTO_RANGE_ENABLE_MOTION_VERSUS_RANGE) 
00116         CASE(SR300_AUTO_RANGE_ENABLE_LASER)               
00117         CASE(SR300_AUTO_RANGE_MIN_MOTION_VERSUS_RANGE)    
00118         CASE(SR300_AUTO_RANGE_MAX_MOTION_VERSUS_RANGE)    
00119         CASE(SR300_AUTO_RANGE_START_MOTION_VERSUS_RANGE)  
00120         CASE(SR300_AUTO_RANGE_MIN_LASER)                  
00121         CASE(SR300_AUTO_RANGE_MAX_LASER)                  
00122         CASE(SR300_AUTO_RANGE_START_LASER)                
00123         CASE(SR300_AUTO_RANGE_UPPER_THRESHOLD) 
00124         CASE(SR300_AUTO_RANGE_LOWER_THRESHOLD)
00125         CASE(R200_LR_AUTO_EXPOSURE_ENABLED)
00126         CASE(R200_LR_GAIN)
00127         CASE(R200_LR_EXPOSURE)
00128         CASE(R200_EMITTER_ENABLED)
00129         CASE(R200_DEPTH_UNITS)
00130         CASE(R200_DEPTH_CLAMP_MIN)
00131         CASE(R200_DEPTH_CLAMP_MAX)
00132         CASE(R200_DISPARITY_MULTIPLIER)
00133         CASE(R200_DISPARITY_SHIFT)
00134         CASE(R200_AUTO_EXPOSURE_MEAN_INTENSITY_SET_POINT)
00135         CASE(R200_AUTO_EXPOSURE_BRIGHT_RATIO_SET_POINT)  
00136         CASE(R200_AUTO_EXPOSURE_KP_GAIN)                 
00137         CASE(R200_AUTO_EXPOSURE_KP_EXPOSURE)             
00138         CASE(R200_AUTO_EXPOSURE_KP_DARK_THRESHOLD)       
00139         CASE(R200_AUTO_EXPOSURE_TOP_EDGE)       
00140         CASE(R200_AUTO_EXPOSURE_BOTTOM_EDGE)    
00141         CASE(R200_AUTO_EXPOSURE_LEFT_EDGE)      
00142         CASE(R200_AUTO_EXPOSURE_RIGHT_EDGE)     
00143         CASE(R200_DEPTH_CONTROL_ESTIMATE_MEDIAN_DECREMENT)   
00144         CASE(R200_DEPTH_CONTROL_ESTIMATE_MEDIAN_INCREMENT)   
00145         CASE(R200_DEPTH_CONTROL_MEDIAN_THRESHOLD)            
00146         CASE(R200_DEPTH_CONTROL_SCORE_MINIMUM_THRESHOLD)     
00147         CASE(R200_DEPTH_CONTROL_SCORE_MAXIMUM_THRESHOLD)     
00148         CASE(R200_DEPTH_CONTROL_TEXTURE_COUNT_THRESHOLD)     
00149         CASE(R200_DEPTH_CONTROL_TEXTURE_DIFFERENCE_THRESHOLD)
00150         CASE(R200_DEPTH_CONTROL_SECOND_PEAK_THRESHOLD)       
00151         CASE(R200_DEPTH_CONTROL_NEIGHBOR_THRESHOLD)
00152         CASE(R200_DEPTH_CONTROL_LR_THRESHOLD)
00153         CASE(FISHEYE_EXPOSURE)
00154         CASE(FISHEYE_GAIN)
00155         CASE(FISHEYE_STROBE)
00156         CASE(FISHEYE_EXTERNAL_TRIGGER)
00157         CASE(FRAMES_QUEUE_SIZE)
00158         CASE(TOTAL_FRAME_DROPS)
00159         CASE(FISHEYE_ENABLE_AUTO_EXPOSURE)
00160         CASE(FISHEYE_AUTO_EXPOSURE_MODE)
00161         CASE(FISHEYE_AUTO_EXPOSURE_ANTIFLICKER_RATE)
00162         CASE(FISHEYE_AUTO_EXPOSURE_PIXEL_SAMPLE_RATE)
00163         CASE(FISHEYE_AUTO_EXPOSURE_SKIP_FRAMES)
00164         CASE(HARDWARE_LOGGER_ENABLED)
00165         default: assert(!is_valid(value)); return unknown;
00166         }
00167         #undef CASE
00168     }
00169 
00170     const char * get_string(rs_source value)
00171     {
00172         #define CASE(X) case RS_SOURCE_##X: return #X;
00173         switch(value)
00174         {
00175         CASE(VIDEO)
00176         CASE(MOTION_TRACKING)
00177         CASE(ALL)
00178         default: assert(!is_valid(value)); return unknown;
00179         }
00180         #undef CASE
00181     }
00182     
00183     const char * get_string(rs_capabilities value)
00184     {
00185         #define CASE(X) case RS_CAPABILITIES_##X: return #X;
00186         switch(value)
00187         {
00188         CASE(DEPTH)
00189         CASE(COLOR)
00190         CASE(INFRARED)
00191         CASE(INFRARED2)
00192         CASE(FISH_EYE)
00193         CASE(MOTION_EVENTS)
00194         CASE(MOTION_MODULE_FW_UPDATE)
00195         CASE(ADAPTER_BOARD)
00196         CASE(ENUMERATION)
00197         default: assert(!is_valid(value)); return unknown;
00198         }
00199         #undef CASE
00200     }
00201 
00202     const char * get_string(rs_event_source value)
00203     {
00204         #define CASE(X) case RS_EVENT_##X: return #X;
00205         switch(value)
00206         {
00207         CASE(IMU_ACCEL)
00208         CASE(IMU_GYRO)
00209         CASE(IMU_DEPTH_CAM)
00210         CASE(IMU_MOTION_CAM)
00211         CASE(G0_SYNC)
00212         CASE(G1_SYNC)
00213         CASE(G2_SYNC)
00214         default: assert(!is_valid(value)); return unknown;
00215         }
00216         #undef CASE
00217     }
00218 
00219     const char * get_string(rs_blob_type value)
00220     {
00221         #define CASE(X) case RS_BLOB_TYPE_##X: return #X;
00222         switch(value)
00223         {
00224         CASE(MOTION_MODULE_FIRMWARE_UPDATE)
00225         default: assert(!is_valid(value)); return unknown;
00226         }
00227         #undef CASE
00228     }
00229 
00230     const char * get_string(rs_camera_info value)
00231     {
00232         #define CASE(X) case RS_CAMERA_INFO_##X: return #X;
00233         switch(value)
00234         {
00235         CASE(DEVICE_NAME)
00236         CASE(DEVICE_SERIAL_NUMBER)
00237         CASE(CAMERA_FIRMWARE_VERSION)
00238         CASE(ADAPTER_BOARD_FIRMWARE_VERSION)
00239         CASE(MOTION_MODULE_FIRMWARE_VERSION)
00240         CASE(IMAGER_MODEL_NUMBER)
00241         CASE(CAMERA_TYPE)
00242         CASE(OEM_ID)
00243         CASE(MODULE_VERSION)
00244         CASE(BUILD_DATE)
00245         CASE(CALIBRATION_DATE)
00246         CASE(PROGRAM_DATE)
00247         CASE(FOCUS_ALIGNMENT_DATE)
00248         CASE(FOCUS_VALUE)
00249         CASE(CONTENT_VERSION)
00250         CASE(ISP_FW_VERSION)
00251         CASE(LENS_TYPE)
00252         CASE(LENS_COATING__TYPE)
00253         CASE(NOMINAL_BASELINE)
00254         CASE(3RD_LENS_TYPE)
00255         CASE(3RD_LENS_COATING_TYPE)
00256         CASE(3RD_NOMINAL_BASELINE)
00257         CASE(EMITTER_TYPE)
00258         default: assert(!is_valid(value)); return unknown;
00259         }
00260         #undef CASE
00261     }
00262 
00263     const char * get_string(rs_frame_metadata value)
00264     {
00265         #define CASE(X) case RS_FRAME_METADATA_##X: return #X;
00266         switch (value)
00267         {
00268         CASE(ACTUAL_EXPOSURE)
00269         CASE(ACTUAL_FPS)
00270         default: assert(!is_valid(value)); return unknown;
00271         }
00272         #undef CASE
00273     }
00274 
00275     const char * get_string(rs_timestamp_domain value)
00276     {
00277         #define CASE(X) case RS_TIMESTAMP_DOMAIN_##X: return #X;
00278         switch (value)
00279         {
00280         CASE(CAMERA)
00281         CASE(MICROCONTROLLER)
00282         default: assert(!is_valid(value)); return unknown;
00283         }
00284         #undef CASE
00285     }
00286 
00287     size_t subdevice_mode_selection::get_image_size(rs_stream stream) const
00288     {
00289         return rsimpl::get_image_size(get_width(), get_height(), get_format(stream));
00290     }
00291 
00292     void subdevice_mode_selection::set_output_buffer_format(const rs_output_buffer_format in_output_format)
00293     {
00294         output_format = in_output_format;
00295     }
00296 
00297     void subdevice_mode_selection::unpack(byte * const dest[], const byte * source) const
00298     {
00299         const int MAX_OUTPUTS = 2;
00300         const auto & outputs = get_outputs();        
00301         assert(outputs.size() <= MAX_OUTPUTS);
00302 
00303         // Determine input stride (and apply cropping)
00304         const byte * in = source;
00305         size_t in_stride = mode.pf.get_image_size(mode.native_dims.x, 1);
00306         if(pad_crop < 0) in += in_stride * -pad_crop + mode.pf.get_image_size(-pad_crop, 1);
00307 
00308         // Determine output stride (and apply padding)
00309         byte * out[MAX_OUTPUTS];
00310         size_t out_stride[MAX_OUTPUTS] = { 0 };
00311         for(size_t i=0; i<outputs.size(); ++i)
00312         {
00313             out[i] = dest[i];
00314             out_stride[i] = rsimpl::get_image_size(get_width(), 1, outputs[i].second);
00315             if(pad_crop > 0) out[i] += out_stride[i] * pad_crop + rsimpl::get_image_size(pad_crop, 1, outputs[i].second);
00316         }
00317 
00318         // Unpack (potentially a subrect of) the source image into (potentially a subrect of) the destination buffers
00319         const int unpack_width = get_unpacked_width(), unpack_height = get_unpacked_height();
00320         if(mode.native_dims.x == get_width())
00321         {
00322             // If not strided, unpack as though it were a single long row
00323             mode.pf.unpackers[unpacker_index].unpack(out, in, unpack_width * unpack_height);
00324         }
00325         else
00326         {
00327             
00328             // Otherwise unpack one row at a time
00329             assert(mode.pf.plane_count == 1); // Can't unpack planar formats row-by-row (at least not with the current architecture, would need to pass multiple source ptrs to unpack)
00330             for(int i=0; i<unpack_height; ++i)
00331             {
00332                 mode.pf.unpackers[unpacker_index].unpack(out, in, unpack_width);
00333                 for(size_t i=0; i<outputs.size(); ++i) out[i] += out_stride[i];
00334                 in += in_stride;
00335             }
00336         }
00337     }
00338 
00339     int subdevice_mode_selection::get_unpacked_width() const
00340     {
00341         return std::min(mode.native_intrinsics.width, get_width());
00342     }
00343 
00344     int subdevice_mode_selection::get_unpacked_height() const
00345     {
00346         return std::min(mode.native_intrinsics.height, get_height());
00347     }
00348 
00350     // static_device_info //
00352 
00353     bool stream_request::contradict(stream_request req) const
00354     {
00355         if (((format != RS_FORMAT_ANY && format != req.format) ||
00356             (width != 0 && width != req.width) ||
00357             (height != 0 && height != req.height) ||
00358             (fps != 0 && fps != req.fps) ||
00359             (output_format != req.output_format)))
00360             return true;
00361         return false;
00362     }
00363 
00364     bool stream_request::is_filled() const
00365     {
00366         return width != 0 && height != 0 && format != RS_FORMAT_ANY && fps != 0;
00367     }
00368 
00369     static_device_info::static_device_info() : num_libuvc_transfer_buffers(1), nominal_depth_scale(0.001f)
00370     {
00371         for(auto & s : stream_subdevices) s = -1;
00372         for(auto & s : data_subdevices) s = -1;
00373         for(auto & s : presets) for(auto & p : s) p = stream_request();
00374         for(auto & p : stream_poses)
00375         {
00376             p = {{{1,0,0},{0,1,0},{0,0,1}}, {0,0,0}};
00377         }
00378     }
00379 
00380     // search_request_params are used to find first request that satisfies cameras set of constraints
00381     // each search_request_params represents requests for each stream type + index of current stream type under examination
00382     struct search_request_params
00383     {
00384         stream_request requests[RS_STREAM_NATIVE_COUNT];
00385         int stream;
00386         search_request_params(stream_request in_requests[RS_STREAM_NATIVE_COUNT], int i)
00387             : stream(i)
00388         {
00389             for (auto i = 0; i<RS_STREAM_NATIVE_COUNT; i++)
00390             {
00391                 requests[i] = in_requests[i];
00392             }
00393         }
00394     };
00395 
00396     bool device_config::all_requests_filled(const stream_request(&requests)[RS_STREAM_NATIVE_COUNT]) const
00397     {
00398         for (auto i = 0; i<RS_STREAM_NATIVE_COUNT; i++)
00399         {
00400             if (requests[i].enabled &&
00401                 (requests[i].height == 0 ||
00402                 requests[i].width == 0 ||
00403                 requests[i].format == RS_FORMAT_ANY ||
00404                 requests[i].fps == 0))
00405                 return false;
00406         }
00407         return true;
00408     }
00409 
00410     // find_good_requests_combination is used to find requests that satisfy cameras set of constraints.
00411     // this is done using BFS search over the posibility space.
00412     // the algorithm:
00413     // start with initial combination of streams requests- the input requests, can be empty or partially filled by user
00414     // insert initial combination to a queue data structure (dequeu for performance)
00415     // loop until queue is empty - at each iteration pop from queue the next set of requests.
00416     // for each one of the next stream request posibilties create new items by adding them to current item and pushing them back to queue.
00417     // once there is a item that all its stream requsts are filled 
00418     // and validated to satisfies all interstream constraints
00419     // copy it to requests parameter and return true.
00420     bool device_config::find_good_requests_combination( stream_request(&requests)[RS_STREAM_NATIVE_COUNT], std::vector<stream_request> stream_requests[RS_STREAM_NATIVE_COUNT]) const
00421     {
00422         std::deque<search_request_params> calls;
00423   
00424         // initial parameter is the input requests 
00425         // and its stream index is 0 (depth)
00426         search_request_params p = { requests, 0 };
00427         calls.push_back(p);
00428 
00429         while (!calls.empty())
00430         {
00431             //pop one item
00432             p = calls.front();
00433             calls.pop_front();
00434 
00435             //check if found combination that satisfies all interstream constraints
00436             if (all_requests_filled(p.requests) && validate_requests(p.requests))
00437             {
00438                 for (auto i = 0; i < RS_STREAM_NATIVE_COUNT; i++)
00439                 {
00440                     requests[i] = p.requests[i];
00441                 }
00442                 return true;
00443             }
00444 
00445             //if this stream is not enabled or already filled move to next item 
00446             if (!requests[p.stream].enabled || requests[p.stream].is_filled()) 
00447             {
00448                 // push the new requests parameter with stream =  stream + 1
00449                 search_request_params new_p = { p.requests, p.stream + 1 };
00450                 calls.push_back(new_p);
00451                 continue;
00452             }
00453 
00454             //now need to go over all posibilities for the next stream
00455             for (size_t i = 0; i < stream_requests[p.stream].size(); i++)
00456             {
00457 
00458                 //check that this spasific request is not contradicts the original user request
00459                 if (!requests[p.stream].contradict(stream_requests[p.stream][i]))
00460                 {
00461                     //add to request the next option from possible requests
00462                     p.requests[p.stream] = stream_requests[p.stream][i];
00463 
00464                     //if after adding the next stream request if it doesn't satisfies all interstream constraints
00465                     //do not insert it to queue
00466                     if (validate_requests(p.requests))
00467                     { 
00468                         // push the new requests parameter with stream =  stream + 1
00469                         search_request_params new_p = { p.requests, p.stream + 1 };
00470                         calls.push_back(new_p);
00471                     }
00472                 }
00473             }
00474 
00475         }
00476         //if deque is empty and no good requests combination found return false
00477         return false;
00478     }
00479 
00480     bool device_config::fill_requests(stream_request(&requests)[RS_STREAM_NATIVE_COUNT]) const
00481     {
00482         //did the user filled all requests?
00483         if(all_requests_filled(requests))
00484         {
00485             return true;
00486         }
00487 
00488         //If the user did not fill all requests, we need to fill the missing requests
00489 
00490         std::vector<stream_request> stream_requests[RS_STREAM_NATIVE_COUNT];
00491         //Get all requests posibilities in order to find the requests that satisfies interstream constraints
00492         get_all_possible_requestes(stream_requests);
00493 
00494         //find stream requests combination that satisfies all interstream constraints
00495         return find_good_requests_combination(requests, stream_requests);
00496     }
00497 
00498     void device_config::get_all_possible_requestes(std::vector<stream_request>(&stream_requests)[RS_STREAM_NATIVE_COUNT]) const
00499     {
00500         for (size_t i = 0; i < info.subdevice_modes.size(); i++)
00501         {
00502             stream_request request;
00503             auto mode = info.subdevice_modes[i];
00504 
00505             for (auto pad_crop : mode.pad_crop_options)
00506             {
00507                 for (auto & unpacker : mode.pf.unpackers)
00508                 {
00509                     auto selection = subdevice_mode_selection(mode, pad_crop, int(&unpacker - mode.pf.unpackers.data()));
00510 
00511                     request.enabled = true;
00512                     request.fps = selection.get_framerate();
00513                     request.height = selection.get_height();
00514                     request.width = selection.get_width();
00515                     auto outputs = selection.get_outputs();
00516 
00517                     for (auto output : outputs)
00518                     {
00519                         request.format = output.second;
00520                         for (auto output_format = static_cast<int>(RS_OUTPUT_BUFFER_FORMAT_CONTINUOUS); output_format < static_cast<int>(RS_OUTPUT_BUFFER_FORMAT_COUNT); output_format++)
00521                         {
00522                             request.output_format = static_cast<rs_output_buffer_format>(output_format);
00523                             stream_requests[output.first].push_back(request);
00524                         }
00525                     }
00526                 }
00527             }
00528         }
00529     }
00530 
00531     subdevice_mode_selection device_config::select_mode(const  stream_request(&requests)[RS_STREAM_NATIVE_COUNT], int subdevice_index) const
00532     {
00533         // Determine if the user has requested any streams which are supplied by this subdevice
00534         auto any_stream_requested = false;
00535         std::array<bool, RS_STREAM_NATIVE_COUNT> stream_requested = {};
00536         for(int j = 0; j < RS_STREAM_NATIVE_COUNT; ++j)
00537         {
00538             if(requests[j].enabled && info.stream_subdevices[j] == subdevice_index)
00539             {
00540                 stream_requested[j] = true;
00541                 any_stream_requested = true;
00542             }
00543         }
00544 
00545         // If no streams were requested, skip to the next subdevice
00546         if(!any_stream_requested) return subdevice_mode_selection();
00547 
00548         // Look for an appropriate mode
00549         for(auto & subdevice_mode : info.subdevice_modes)
00550         {
00551             // Skip modes that apply to other subdevices
00552             if(subdevice_mode.subdevice != subdevice_index) continue;
00553 
00554            
00555             for(auto pad_crop : subdevice_mode.pad_crop_options)
00556             {
00557                 for(auto & unpacker : subdevice_mode.pf.unpackers)
00558                 {
00559                     auto selection = subdevice_mode_selection(subdevice_mode, pad_crop, (int)(&unpacker - subdevice_mode.pf.unpackers.data()));
00560 
00561                     // Determine if this mode satisfies the requirements on our requested streams
00562                     auto stream_unsatisfied = stream_requested;
00563                     for(auto & output : unpacker.outputs)
00564                     {
00565                         const auto & req = requests[output.first];
00566                         
00567                         selection.set_output_buffer_format(req.output_format);
00568                         if(req.enabled && (req.width == selection.get_width() )
00569                                        && (req.height == selection.get_height())
00570                                        && (req.format == selection.get_format(output.first))
00571                                        && (req.fps == subdevice_mode.fps))
00572                         {
00573                             stream_unsatisfied[output.first] = false;
00574                         }
00575                     }
00576 
00577                     // If any requested streams are still unsatisfied, skip to the next mode
00578                     if(std::any_of(begin(stream_unsatisfied), end(stream_unsatisfied), [](bool b) { return b; })) continue;
00579                     return selection;
00580                 }
00581             }
00582         }
00583 
00584         // If we did not find an appropriate mode, report an error
00585         std::ostringstream ss;
00586         ss << "uvc subdevice " << subdevice_index << " cannot provide";
00587         bool first = true;
00588         for(int j = 0; j < RS_STREAM_NATIVE_COUNT; ++j)
00589         {
00590             if(!stream_requested[j]) continue;
00591             ss << (first ? " " : " and ");
00592             ss << requests[j].width << 'x' << requests[j].height << ':' << get_string(requests[j].format);
00593             ss << '@' << requests[j].fps << "Hz " << get_string((rs_stream)j);
00594             first = false;
00595         }
00596         throw std::runtime_error(ss.str());
00597     }
00598 
00599     std::vector<subdevice_mode_selection> device_config::select_modes(const stream_request (&reqs)[RS_STREAM_NATIVE_COUNT]) const
00600     {
00601         // Make a mutable copy of our array
00602         stream_request requests[RS_STREAM_NATIVE_COUNT];
00603         for (int i = 0; i<RS_STREAM_NATIVE_COUNT; ++i) requests[i] = reqs[i];
00604 
00605         //Validate that user requests satisfy all interstream constraints 
00606         validate_requests(requests, true);
00607 
00608         //Fill the requests that user did not fill
00609         fill_requests(requests);
00610 
00611         // Select subdevice modes needed to satisfy our requests
00612         int num_subdevices = 0;
00613         for(auto & mode : info.subdevice_modes) num_subdevices = std::max(num_subdevices, mode.subdevice+1);
00614         std::vector<subdevice_mode_selection> selected_modes;
00615         for(int i = 0; i < num_subdevices; ++i)
00616         {
00617             auto selection = select_mode(requests, i);
00618             if(selection.mode.pf.fourcc) selected_modes.push_back(selection);
00619         }
00620         return selected_modes;
00621     }
00622 
00623     bool device_config::validate_requests(stream_request(&requests)[RS_STREAM_NATIVE_COUNT], bool throw_exception) const
00624     {
00625         // Check and modify requests to enforce all interstream constraints
00626 
00627         for (auto & rule : info.interstream_rules)
00628         {
00629             auto & a = requests[rule.a], &b = requests[rule.b]; auto f = rule.field;
00630             if (a.enabled && b.enabled)
00631             {
00632                 bool compat = true;
00633                 std::stringstream error_message;
00634 
00635                 if (rule.same_format)
00636                 {
00637                     if ((a.format != RS_FORMAT_ANY) && (b.format != RS_FORMAT_ANY) && (a.format != b.format))
00638                     {
00639                         if (throw_exception) error_message << rule.a << " format (" << rs_format_to_string(a.format) << ") must be equal to " << rule.b << " format (" << rs_format_to_string(b.format) << ")!";
00640                         compat = false;
00641                     }
00642                 }
00643                 else if((a.*f != 0) && (b.*f != 0))
00644                 {
00645                     if ((rule.bigger == RS_STREAM_COUNT) && (!rule.divides && !rule.divides2))
00646                     {
00647                         // Check for incompatibility if both values specified
00648                         if ((a.*f + rule.delta != b.*f) && (a.*f + rule.delta2 != b.*f))
00649                         {
00650                             if (throw_exception) error_message << " " << rule.b << " value " << b.*f << " must be equal to either " << (a.*f + rule.delta) << " or " << (a.*f + rule.delta2) << "!";
00651                             compat = false;
00652                         }
00653                     }
00654                     else
00655                     {
00656                         if (((rule.bigger == rule.a) && (a.*f < b.*f)) || ((rule.bigger == rule.b) && (b.*f < a.*f)))
00657                         {
00658                             if (throw_exception) error_message << " " << rule.a << " value " << a.*f << " must be " << ((rule.bigger == rule.a) ? "bigger" : "smaller") << " then " << rule.b << " value " << b.*f << "!";
00659                             compat = false;
00660                         }
00661                         if ((rule.divides &&  (a.*f % b.*f)) || (rule.divides2 && (b.*f % a.*f)))
00662                         {
00663                             if (throw_exception) error_message << " " << rule.a << " value " << a.*f << " must " << (rule.divides ? "be divided by" : "divide") << rule.b << " value " << b.*f << "!";
00664                             compat = false;
00665                         }
00666                     }
00667                 }
00668                 if (!compat)
00669                 {
00670                     if (throw_exception)
00671                         throw std::runtime_error(to_string() << "requested settings for " << rule.a << " and " << rule.b << " are incompatible!" << error_message.str());
00672                     return false;
00673                 }
00674             }
00675         }
00676         return true;
00677     }
00678 
00679     std::string firmware_version::to_string() const
00680     {
00681         if (is_any) return "any";
00682 
00683         std::stringstream s;
00684         s << std::setfill('0') << std::setw(2) << m_major << "." 
00685             << std::setfill('0') << std::setw(2) << m_minor << "." 
00686             << std::setfill('0') << std::setw(2) << m_patch << "." 
00687             << std::setfill('0') << std::setw(2) << m_build;
00688         return s.str();
00689     }
00690 
00691     std::vector<std::string> firmware_version::split(const std::string& str)
00692     {
00693         std::vector<std::string> result;
00694         auto e = str.end();
00695         auto i = str.begin();
00696         while (i != e){
00697             i = find_if_not(i, e, [](char c) { return c == '.'; });
00698             if (i == e) break;
00699             auto j = find(i, e, '.');
00700             result.emplace_back(i, j);
00701             i = j;
00702         }
00703         return result;
00704     }
00705 
00706     int firmware_version::parse_part(const std::string& name, int part)
00707     {
00708         return atoi(split(name)[part].c_str());
00709     }
00710 
00711     calibration_validator::calibration_validator(std::function<bool(rs_stream, rs_stream)> extrinsic_validator, std::function<bool(rs_stream)> intrinsic_validator)
00712         : extrinsic_validator(extrinsic_validator), intrinsic_validator(intrinsic_validator)
00713     {
00714     }
00715 
00716     calibration_validator::calibration_validator()
00717         : extrinsic_validator([](rs_stream, rs_stream) { return true; }), intrinsic_validator([](rs_stream) { return true; })
00718     {
00719     }
00720 
00721     bool calibration_validator::validate_extrinsics(rs_stream from_stream, rs_stream to_stream) const
00722     {
00723         return extrinsic_validator(from_stream, to_stream);
00724     }
00725     bool calibration_validator::validate_intrinsics(rs_stream stream) const
00726     {
00727         return intrinsic_validator(stream);
00728     }
00729 
00730 }


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