1 /*############################################################################
2   # Copyright Intel Corporation
3   #
4   # SPDX-License-Identifier: MIT
5   ############################################################################*/
6 
7 #pragma once
8 
9 #include <algorithm>
10 #include <functional>
11 #include <map>
12 #include <memory>
13 #include <string>
14 #include <utility>
15 #include <vector>
16 
17 #include "vpl/preview/defs.hpp"
18 #include "vpl/preview/exception.hpp"
19 
20 #include "vpl/mfxcommon.h"
21 
22 #include "vpl/preview/detail/string_helpers.hpp"
23 
24 namespace oneapi {
25 namespace vpl {
26 
27 /// @brief Base class to store implementation capabilities
28 class base_implementation_capabilities {
29 public:
30     /// @brief Default ctor
31     /// @param ID of the implementation capabilities format ID.
base_implementation_capabilities(uint32_t ID)32     explicit base_implementation_capabilities(uint32_t ID) : id_(ID) {}
33 
34     /// @brief returns implementation capabilities format ID.
35     /// @return ID of the implementation capabilities format type.
get_id() const36     uint32_t get_id() const {
37         return id_;
38     }
39 
40 protected:
41     /// ID of the implementation capabilities format type.
42     uint32_t id_;
43 };
44 
45 /// @brief Provides information about supported pool policies
46 class pool_policies {
47 public:
48     /// @brief Default ctor
49     /// @param pool policies
pool_policies(mfxPoolPolicyDescription * base)50     explicit pool_policies(mfxPoolPolicyDescription* base) : base_(base) {}
51 
52     /// @brief Provides list of supported policies.
53     /// @return list of policies.
policies() const54     std::vector<mfxPoolAllocationPolicy> policies() const {
55         std::vector<mfxPoolAllocationPolicy> result;
56 
57         std::for_each(base_->Policy,
58                         base_->Policy + base_->NumPoolPolicies,
59                         [&](auto item) {
60                             result.push_back(item);
61                         });
62 
63         return result;
64     }
65 protected:
66     mfxPoolPolicyDescription* base_;
67 };
68 
69 /// @brief Store and parse implementation capabilities in a form of implementation description structure
70 class implementation_capabilities : public base_implementation_capabilities {
71 public:
72     /// @brief Default ctor
73     /// @param caps pointer to raw data.
implementation_capabilities(mfxImplDescription * caps)74     explicit implementation_capabilities(mfxImplDescription *caps)
75             : base_implementation_capabilities(MFX_IMPLCAPS_IMPLDESCSTRUCTURE),
76               caps_(caps) {}
77 
78 public:
79     /// @brief Provides information about supported memory for codecs
80     /// @tparam T Encoder of decoder identifier.
81     template <typename T>
82     class codec_memory {
83     public:
84         /// @brief Default ctor
85         /// @param memdesc Memory description
codec_memory(T memdesc)86         explicit codec_memory(T memdesc) : memdesc_(memdesc) {}
87 
88         /// @brief provides supported memory type.
89         /// @return Memory type.
get_mem_type() const90         mfxResourceType get_mem_type() const {
91             return memdesc_.MemHandleType;
92         }
93 
94         /// @brief provides minimal supported width and height.
95         /// @return minimal supported width and height.
get_min_size() const96         auto get_min_size() const {
97             return std::pair(memdesc_.Width.Min, memdesc_.Height.Min);
98         }
99 
100         /// @brief provides maximal supported width and height.
101         /// @return maximal supported width and height.
get_max_size() const102         auto get_max_size() const {
103             return std::pair(memdesc_.Width.Max, memdesc_.Height.Max);
104         }
105 
106         /// @brief provides increment value for width and height.
107         /// @return increment value for width and height.
get_size_step() const108         auto get_size_step() const {
109             return std::pair(memdesc_.Width.Step, memdesc_.Height.Step);
110         }
111 
112         /// @brief Provides list of supported output memory types.
113         /// @return List of supported output memory types.
get_out_mem_types() const114         std::vector<uint32_t> get_out_mem_types() const {
115             return std::vector<uint32_t>(memdesc_.ColorFormats,
116                                          memdesc_.ColorFormats + memdesc_.NumColorFormats);
117         }
118 
119     protected:
120         /// Raw data
121         T memdesc_;
122     };
123 
124     /// Defines decoder memory description class
125     typedef codec_memory<mfxDecoderDescription::decoder::decprofile::decmemdesc> decoder_memory;
126     /// Defines encoder memory description class
127     typedef codec_memory<mfxEncoderDescription::encoder::encprofile::encmemdesc> encoder_memory;
128 
129     /// @brief Provides information about supported memory formats for VPP filters
130     class vpp_memory_format {
131     public:
132         /// @brief Default ctor
133         /// @param fmt Memory format
vpp_memory_format(mfxVPPDescription::filter::memdesc::format fmt)134         explicit vpp_memory_format(mfxVPPDescription::filter::memdesc::format fmt) : fmt_(fmt) {}
135 
136         /// @brief Returns input memory type in a form of FourCC code
137         /// @return input memory type in a form of FourCC code
get_input_format() const138         uint32_t get_input_format() const {
139             return fmt_.InFormat;
140         }
141 
142         /// @brief Returns iterable list of output memory types in a form of FourCC code
143         /// @return list of output memory types
get_out_format() const144         std::vector<uint32_t> get_out_format() const {
145             return std::vector<uint32_t>(fmt_.OutFormats, fmt_.OutFormats + fmt_.NumOutFormat);
146         }
147 
148     protected:
149         /// Raw data
150         mfxVPPDescription::filter::memdesc::format fmt_;
151     };
152 
153     /// @brief Provides information about supported memory for VPP filters
154     class vpp_memory {
155     public:
156         /// @brief Default ctor
157         /// @param memdesc Memory description
vpp_memory(mfxVPPDescription::filter::memdesc memdesc)158         explicit vpp_memory(mfxVPPDescription::filter::memdesc memdesc) : memdesc_(memdesc) {}
159 
160         /// @brief provides supported memory type.
161         /// @return Memory type.
get_mem_type() const162         mfxResourceType get_mem_type() const {
163             return memdesc_.MemHandleType;
164         }
165 
166         /// @brief provides minimal supported width and height.
167         /// @return minimal supported width and height.
get_min_size() const168         auto get_min_size() const {
169             return std::pair(memdesc_.Width.Min, memdesc_.Height.Min);
170         }
171 
172         /// @brief provides maximal supported width and height.
173         /// @return maximal supported width and height.
get_max_size() const174         auto get_max_size() const {
175             return std::pair(memdesc_.Width.Max, memdesc_.Height.Max);
176         }
177 
178         /// @brief provides increment value for width and height.
179         /// @return increment value for width and height.
get_size_step() const180         auto get_size_step() const {
181             return std::pair(memdesc_.Width.Step, memdesc_.Height.Step);
182         }
183 
184         /// @brief Provides list of supported memory formats.
185         /// @return List of supported memory formats.
get_memory_formats() const186         std::vector<vpp_memory_format> get_memory_formats() const {
187             std::vector<vpp_memory_format> formats;
188 
189             std::for_each(memdesc_.Formats,
190                           memdesc_.Formats + memdesc_.NumInFormats,
191                           [&](mfxVPPDescription::filter::memdesc::format fmt) {
192                               formats.push_back(vpp_memory_format(fmt));
193                           });
194 
195             return formats;
196         }
197 
198     protected:
199         /// Raw data
200         mfxVPPDescription::filter::memdesc memdesc_;
201     };
202 
203     /// @brief Provides information about supported profiles by the decoder
204     class decoder_profile {
205     public:
206         /// @brief Default ctor
207         /// @param profile Decoder profile
decoder_profile(mfxDecoderDescription::decoder::decprofile profile)208         explicit decoder_profile(mfxDecoderDescription::decoder::decprofile profile)
209                 : profile_(profile) {}
210 
211         /// @brief provides ID of the profile.
212         /// @return ID of the profile.
get_profile() const213         uint16_t get_profile() const {
214             return profile_.Profile;
215         }
216 
217         /// @brief Provides list of memory types.
218         /// @return list of memory types.
get_decoder_mem_types() const219         std::vector<decoder_memory> get_decoder_mem_types() const {
220             std::vector<decoder_memory> memories;
221 
222             std::for_each(profile_.MemDesc,
223                           profile_.MemDesc + profile_.NumMemTypes,
224                           [&](mfxDecoderDescription::decoder::decprofile::decmemdesc memdesc) {
225                               memories.push_back(decoder_memory(memdesc));
226                           });
227 
228             return memories;
229         }
230 
231     protected:
232         /// Raw data
233         mfxDecoderDescription::decoder::decprofile profile_;
234     };
235 
236     /// @brief Provides information about supported profiles by the encoder
237     class encoder_profile {
238     public:
239         /// @brief Default ctor
240         /// @param profile Encoder profile
encoder_profile(mfxEncoderDescription::encoder::encprofile profile)241         explicit encoder_profile(mfxEncoderDescription::encoder::encprofile profile)
242                 : profile_(profile) {}
243 
244         /// @brief provides ID of the profile.
245         /// @return ID of the profile.
get_profile() const246         uint16_t get_profile() const {
247             return profile_.Profile;
248         }
249 
250         /// @brief Provides list of memory types.
251         /// @return list of memory types.
get_encoder_mem_types() const252         std::vector<encoder_memory> get_encoder_mem_types() const {
253             std::vector<encoder_memory> memories;
254 
255             std::for_each(profile_.MemDesc,
256                           profile_.MemDesc + profile_.NumMemTypes,
257                           [&](mfxEncoderDescription::encoder::encprofile::encmemdesc memdesc) {
258                               memories.push_back(encoder_memory(memdesc));
259                           });
260 
261             return memories;
262         }
263 
264     protected:
265         /// Raw data
266         mfxEncoderDescription::encoder::encprofile profile_;
267     };
268 
269     /// @brief Provides information about supported decoders
270     class decoder {
271     public:
272         /// @brief Default ctor
273         /// @param dec decoder
decoder(mfxDecoderDescription::decoder dec)274         explicit decoder(mfxDecoderDescription::decoder dec) : dec_(dec) {}
275 
276         /// @brief Provides codec ID.
277         /// @return Codec ID.
get_codec_id() const278         uint32_t get_codec_id() const {
279             return dec_.CodecID;
280         }
281 
282         /// @brief Provides maximum supported codec's level.
283         /// @return maximum supported codec's level.
get_max_codec_level() const284         uint16_t get_max_codec_level() const {
285             return dec_.MaxcodecLevel;
286         }
287 
288         /// @brief Provides list of supported profiles.
289         /// @return list of profiles.
get_profiles() const290         std::vector<decoder_profile> get_profiles() const {
291             std::vector<decoder_profile> profiles;
292 
293             std::for_each(dec_.Profiles,
294                           dec_.Profiles + dec_.NumProfiles,
295                           [&](mfxDecoderDescription::decoder::decprofile profile) {
296                               profiles.push_back(decoder_profile(profile));
297                           });
298 
299             return profiles;
300         }
301 
302     protected:
303         /// Raw data
304         mfxDecoderDescription::decoder dec_;
305     };
306 
307     /// @brief Provides information about supported encoders
308     class encoder {
309     public:
310         /// @brief Default ctor
311         /// @param enc encoder
encoder(mfxEncoderDescription::encoder enc)312         explicit encoder(mfxEncoderDescription::encoder enc) : enc_(enc) {}
313 
314         /// @brief Provides codec ID.
315         /// @return Codec ID.
get_codec_id() const316         uint32_t get_codec_id() const {
317             return enc_.CodecID;
318         }
319 
320         /// @brief Provides maximum supported codec's level.
321         /// @return maximum supported codec's level.
get_max_codec_level() const322         uint16_t get_max_codec_level() const {
323             return enc_.MaxcodecLevel;
324         }
325 
326         /// @brief Provides information about bidirectional prediction support.
327         /// @return True if bidirectional prediction supported.
get_bidirectional_prediction_support() const328         uint16_t get_bidirectional_prediction_support() const {
329             return enc_.BiDirectionalPrediction;
330         }
331 
332         /// @brief Provides list of supported profiles.
333         /// @return list of profiles.
get_profiles() const334         std::vector<encoder_profile> get_profiles() const {
335             std::vector<encoder_profile> profiles;
336 
337             std::for_each(enc_.Profiles,
338                           enc_.Profiles + enc_.NumProfiles,
339                           [&](mfxEncoderDescription::encoder::encprofile profile) {
340                               profiles.push_back(encoder_profile(profile));
341                           });
342 
343             return profiles;
344         }
345 
346     protected:
347         /// Raw data
348         mfxEncoderDescription::encoder enc_;
349     };
350 
351     /// @brief Provides information about supported VPP filters
352     class vpp_filter {
353     public:
354         /// @brief Default ctor
355         /// @param flt filter
vpp_filter(mfxVPPDescription::filter flt)356         explicit vpp_filter(mfxVPPDescription::filter flt) : flt_(flt) {}
357 
358         /// @brief Provides VPP filter ID.
359         /// @return Filter ID.
get_filter_id() const360         uint32_t get_filter_id() const {
361             return flt_.FilterFourCC;
362         }
363 
364         /// @brief Provides maximum introduced delay by this filter.
365         /// @return Delay in frames.
get_max_delay_in_frames() const366         uint16_t get_max_delay_in_frames() const {
367             return flt_.MaxDelayInFrames;
368         }
369 
370         /// @brief Provides list of supported memory type.
371         /// @return list of memory types.
get_memory_types() const372         std::vector<vpp_memory> get_memory_types() const {
373             std::vector<vpp_memory> memories;
374 
375             std::for_each(flt_.MemDesc,
376                           flt_.MemDesc + flt_.NumMemTypes,
377                           [&](mfxVPPDescription::filter::memdesc memdesc) {
378                               memories.push_back(vpp_memory(memdesc));
379                           });
380 
381             return memories;
382         }
383 
384     protected:
385         /// Raw data
386         mfxVPPDescription::filter flt_;
387     };
388 
389     /// @brief Provides type of the implementation: SW or HW.
390     /// @return Type of the implementation.
get_impl_type() const391     mfxImplType get_impl_type() const {
392         return caps_->Impl;
393     }
394 
395     /// @brief Provides acceleration mode of the implementation.
396     /// @return Type of the implementation.
397     /// @todo Port to api 2.1 is reqired
get_acceleration_mode() const398     mfxAccelerationMode get_acceleration_mode() const {
399         return caps_->AccelerationMode;
400     }
401 
402     /// @brief Provides supported API version of the implementation.
403     /// @return API version.
get_api_version() const404     mfxVersion get_api_version() const {
405         return caps_->ApiVersion;
406     }
407 
408     /// @brief Provides name of the implementation.
409     /// @return Null terminated string with the name of the implementation.
get_impl_name() const410     std::string get_impl_name() const {
411         return std::string(caps_->ImplName);
412     }
413 
414     /// @brief Provides license of the implementation.
415     /// @return Null terminated string with the license of the implementation.
get_license_name() const416     std::string get_license_name() const {
417         return std::string(caps_->License);
418     }
419 
420     /// @brief Provides keywords of the implementation.
421     /// @return Null terminated string with the keywords of the implementation.
get_keywords_name() const422     std::string get_keywords_name() const {
423         return std::string(caps_->Keywords);
424     }
425 
426     /// @brief Provides vendor ID.
427     /// @return Vendor ID.
get_vendor_id() const428     uint32_t get_vendor_id() const {
429         return caps_->VendorID;
430     }
431 
432     /// @brief Provides vendor's implementation ID.
433     /// @return vendor's implementation ID.
get_vendor_impl_id() const434     uint32_t get_vendor_impl_id() const {
435         return caps_->VendorImplID;
436     }
437 
438     /// @brief Provides target device for the implementation.
439     /// @return Null terminated string with device ID (or name).
get_target_device_id() const440     std::string get_target_device_id() const {
441         return std::string(caps_->Dev.DeviceID);
442     }
443 
444     /// @brief Provides list of supported target subdevice IDs.
445     /// @return list of supported target subdevice IDs.
get_target_subdevice_ids() const446     std::vector<std::string> get_target_subdevice_ids() const {
447         std::vector<std::string> subdevices;
448 
449         std::for_each(caps_->Dev.SubDevices,
450                       caps_->Dev.SubDevices + caps_->Dev.NumSubDevices,
451                       [&](mfxDeviceDescription::subdevices sb) {
452                           subdevices.push_back(std::string(sb.SubDeviceID));
453                       });
454 
455         return subdevices;
456     }
457 
458     /// @brief Provides list of supported acceleration modes.
459     /// @return list of supported modes.
get_accel_modes() const460     std::vector<std::string> get_accel_modes() const {
461         std::vector<std::string> accelmodes;
462 
463         if (caps_->AccelerationModeDescription.NumAccelerationModes > 0) {
464             std::for_each(caps_->AccelerationModeDescription.Mode,
465                           caps_->AccelerationModeDescription.Mode +
466                                 caps_->AccelerationModeDescription.NumAccelerationModes,
467                           [&](mfxAccelerationMode mode) {
468                               accelmodes.push_back(detail::AccelerationMode2String(mode));
469                           });
470         }
471 
472         return accelmodes;
473     }
474 
475     /// @brief Provides list of supported decoders.
476     /// @return list of supported decoders.
get_decoders() const477     std::vector<decoder> get_decoders() const {
478         std::vector<decoder> decoders;
479 
480         std::for_each(caps_->Dec.Codecs,
481                       caps_->Dec.Codecs + caps_->Dec.NumCodecs,
482                       [&](mfxDecoderDescription::decoder dec) {
483                           decoders.push_back(decoder(dec));
484                       });
485 
486         return decoders;
487     }
488 
489     /// @brief Provides list of supported encoders.
490     /// @return list of supported encoders.
get_encoders() const491     std::vector<encoder> get_encoders() const {
492         std::vector<encoder> encoders;
493 
494         std::for_each(caps_->Enc.Codecs,
495                       caps_->Enc.Codecs + caps_->Enc.NumCodecs,
496                       [&](mfxEncoderDescription::encoder enc) {
497                           encoders.push_back(encoder(enc));
498                       });
499 
500         return encoders;
501     }
502 
503     /// @brief Provides list of supported VPP filters.
504     /// @return list of supported VPP filters.
get_vpp_filters() const505     std::vector<vpp_filter> get_vpp_filters() const {
506         std::vector<vpp_filter> filters;
507 
508         std::for_each(caps_->VPP.Filters,
509                       caps_->VPP.Filters + caps_->VPP.NumFilters,
510                       [&](mfxVPPDescription::filter flt) {
511                           filters.push_back(vpp_filter(flt));
512                       });
513 
514         return filters;
515     }
516 
517     /// @brief Provides list of supported pool policies.
518     /// @return list of supported pool policies.
get_pool_policies() const519     pool_policies get_pool_policies() const {
520         return pool_policies(&caps_->PoolPolicies);
521     }
522 
523 protected:
524     /// Raw data
525     mfxImplDescription *caps_;
526 
527     /// @brief Friend operator to print out state of the class in human readable form.
528     /// @param[inout] out Reference to the stream to write.
529     /// @param[in] f Referebce to the implementation_capabilities instance to dump the state.
530     /// @return Reference to the stream.
531     friend std::ostream &operator<<(std::ostream &out, const implementation_capabilities &f);
532 };
533 
534 /// @brief Store and parse names of the implemented functions
535 class implemented_functions : public base_implementation_capabilities {
536 public:
537     /// @brief Default ctor
538     /// @param caps pointer to raw data.
implemented_functions(mfxImplementedFunctions * caps)539     explicit implemented_functions(mfxImplementedFunctions *caps)
540             : base_implementation_capabilities(MFX_IMPLCAPS_IMPLEMENTEDFUNCTIONS),
541               caps_(caps) {}
542 
543 public:
544     /// @brief Provides list of implemented functions.
545     /// @return list of implemented functions.
get_functions_name() const546     std::vector<std::string> get_functions_name() const {
547         std::vector<std::string> functions;
548 
549         std::for_each(caps_->FunctionsName,
550                       caps_->FunctionsName + caps_->NumFunctions,
551                       [&](mfxChar* func) {
552                           functions.push_back(func);
553                       });
554 
555         return functions;
556     }
557 protected:
558     /// Raw data
559     mfxImplementedFunctions *caps_;
560 
561     /// @brief Friend operator to print out state of the class in human readable form.
562     /// @param[inout] out Reference to the stream to write.
563     /// @param[in] f Referebce to the implemented_functions instance to dump the state.
564     /// @return Reference to the stream.
565     friend std::ostream &operator<<(std::ostream &out, const implemented_functions &f);
566 };
567 
568 /// @brief Store and parse path to the implementation
569 class implementation_path : public base_implementation_capabilities {
570 public:
571     /// @brief Default ctor
572     /// @param caps pointer to raw data.
implementation_path(mfxChar * path)573     explicit implementation_path(mfxChar *path)
574             : base_implementation_capabilities(MFX_IMPLCAPS_IMPLPATH),
575               path_(path) {}
576 
577 public:
578     /// @brief Provides path to the implementation's shared library.
579     /// @return path to the implementation's shared library.
get_path() const580     std::string get_path() const {
581         return std::string(path_);
582     }
583 protected:
584     /// Raw data
585     mfxChar *path_;
586 
587     /// @brief Friend operator to print out state of the class in human readable form.
588     /// @param[inout] out Reference to the stream to write.
589     /// @param[in] f Referebce to the implemented_functions instance to dump the state.
590     /// @return Reference to the stream.
591     friend std::ostream &operator<<(std::ostream &out, const implementation_path &f);
592 };
593 
594 /// @brief Factory class to create implementation capabilities report class based on the format ID.
595 class implementation_capabilities_factory {
596 public:
597     /// @brief Default ctor
implementation_capabilities_factory()598     implementation_capabilities_factory() {
599         map_[MFX_IMPLCAPS_IMPLDESCSTRUCTURE] = [](void *handle) {
600             return std::make_shared<implementation_capabilities>(
601                 reinterpret_cast<mfxImplDescription *>(handle));
602         };
603         map_[MFX_IMPLCAPS_IMPLEMENTEDFUNCTIONS] = [](void *handle) {
604             return std::make_shared<implemented_functions>(
605                 reinterpret_cast<mfxImplementedFunctions *>(handle));
606         };
607         map_[MFX_IMPLCAPS_IMPLPATH] = [](void *handle) {
608             return std::make_shared<implementation_path>(
609                 reinterpret_cast<mfxChar *>(handle));
610         };
611     }
612 
613     /// @brief Creates instance of implementation capabilities report class based on the format ID
614     /// @param[in] id Requested format ID
615     /// @param[in] handle Handle to read-only raw data to interpret by the implementation capabilities report class
616     /// @return instance of implementation capabilities report class based on the format ID
create(uint32_t id,void * handle)617     std::shared_ptr<base_implementation_capabilities> create(uint32_t id, void *handle) {
618         if (auto it = map_.find(id); it != map_.end())
619             return it->second(handle);
620         throw base_exception(MFX_ERR_UNSUPPORTED);
621     }
622 
623 protected:
624     /// @brief Map of format ID and interpreter instance class creator
625     std::map<uint32_t,
626              std::function<std::shared_ptr<base_implementation_capabilities>(void *handle)>>
627         map_;
628 };
629 
operator <<(std::ostream & out,const implementation_capabilities::decoder_memory & m)630 inline std::ostream &operator<<(std::ostream &out,
631                                 const implementation_capabilities::decoder_memory &m) {
632     out << detail::space(detail::INTENT * 5, out, "MemHandleType = ")
633         << detail::ResourceType2String(m.get_mem_type()) << std::endl;
634     out << detail::space(detail::INTENT * 5, out, "Frame size range = [")
635         << std::get<0>(m.get_min_size()) << "," << std::get<1>(m.get_min_size()) << "]:["
636         << std::get<0>(m.get_max_size()) << "," << std::get<1>(m.get_max_size()) << "]"
637         << std::endl;
638     std::vector<uint32_t> fmts = m.get_out_mem_types();
639     out << detail::space(detail::INTENT * 5, out, "# of color formats = ") << fmts.size()
640         << std::endl;
641     detail::space(detail::INTENT * 6, out, "color format = ");
642     std::for_each(fmts.begin(), fmts.end(), [&](uint32_t fmt) {
643         out << detail::FourCC2String(fmt) << ", ";
644     });
645     out << "\b\b  " << std::endl;
646 
647     return out;
648 }
649 
operator <<(std::ostream & out,const implementation_capabilities::encoder_memory & m)650 inline std::ostream &operator<<(std::ostream &out,
651                                 const implementation_capabilities::encoder_memory &m) {
652     out << detail::space(detail::INTENT * 5, out, "MemHandleType = ")
653         << detail::ResourceType2String(m.get_mem_type()) << std::endl;
654     out << detail::space(detail::INTENT * 5, out, "Frame size range = [")
655         << std::get<0>(m.get_min_size()) << "," << std::get<1>(m.get_min_size()) << "]:["
656         << std::get<0>(m.get_max_size()) << "," << std::get<1>(m.get_max_size()) << "]"
657         << std::endl;
658     std::vector<uint32_t> fmts = m.get_out_mem_types();
659     out << detail::space(detail::INTENT * 5, out, "# of color formats = ") << fmts.size()
660         << std::endl;
661 
662     out << detail::space(detail::INTENT * 6, out, "color formats = ");
663     std::for_each(fmts.begin(), fmts.end(), [&](uint32_t fmt) {
664         out << detail::FourCC2String(fmt) << ", ";
665     });
666     out << "\b\b  " << std::endl;
667 
668     return out;
669 }
670 
operator <<(std::ostream & out,const implementation_capabilities::decoder_profile & p)671 inline std::ostream &operator<<(std::ostream &out,
672                                 const implementation_capabilities::decoder_profile &p) {
673     out << detail::space(detail::INTENT * 4, out, "Profile = ") << p.get_profile() << std::endl;
674 
675     std::vector<implementation_capabilities::decoder_memory> dm = p.get_decoder_mem_types();
676     out << detail::space(detail::INTENT * 4, out, "# memory types = ") << dm.size() << std::endl;
677     std::for_each(dm.begin(), dm.end(), [&](implementation_capabilities::decoder_memory dec_m) {
678         out << dec_m;
679     });
680 
681     return out;
682 }
683 
operator <<(std::ostream & out,const implementation_capabilities::encoder_profile & p)684 inline std::ostream &operator<<(std::ostream &out,
685                                 const implementation_capabilities::encoder_profile &p) {
686     out << detail::space(detail::INTENT * 4, out, "Profile = ") << p.get_profile() << std::endl;
687 
688     std::vector<implementation_capabilities::encoder_memory> em = p.get_encoder_mem_types();
689     out << detail::space(detail::INTENT * 4, out, "# memory types = ") << em.size() << std::endl;
690     std::for_each(em.begin(), em.end(), [&](implementation_capabilities::encoder_memory enc_m) {
691         out << enc_m;
692     });
693 
694     return out;
695 }
696 
operator <<(std::ostream & out,const implementation_capabilities::decoder & d)697 inline std::ostream &operator<<(std::ostream &out, const implementation_capabilities::decoder &d) {
698     out << detail::space(detail::INTENT * 3, out, "CodecID = ")
699         << detail::FourCC2String(d.get_codec_id()) << std::endl;
700     out << detail::space(detail::INTENT * 3, out, "MaxcodecLevel = ") << d.get_max_codec_level()
701         << std::endl;
702 
703     std::vector<implementation_capabilities::decoder_profile> dp = d.get_profiles();
704     out << detail::space(detail::INTENT * 3, out, "# of profiles = ") << dp.size() << std::endl;
705     std::for_each(dp.begin(), dp.end(), [&](implementation_capabilities::decoder_profile dec_p) {
706         out << dec_p;
707     });
708     return out;
709 }
710 
operator <<(std::ostream & out,const implementation_capabilities::encoder & e)711 inline std::ostream &operator<<(std::ostream &out, const implementation_capabilities::encoder &e) {
712     out << detail::space(detail::INTENT * 3, out, "CodecID = ")
713         << detail::FourCC2String(e.get_codec_id()) << std::endl;
714     out << detail::space(detail::INTENT * 3, out, "MaxcodecLevel = ") << e.get_max_codec_level()
715         << std::endl;
716 
717     std::vector<implementation_capabilities::encoder_profile> ep = e.get_profiles();
718     out << detail::space(detail::INTENT * 3, out, "# of profiles = ") << ep.size() << std::endl;
719     std::for_each(ep.begin(), ep.end(), [&](implementation_capabilities::encoder_profile enc_p) {
720         out << enc_p;
721     });
722     return out;
723 }
724 
operator <<(std::ostream & out,const implementation_capabilities::vpp_memory_format & mf)725 inline std::ostream &operator<<(std::ostream &out,
726                                 const implementation_capabilities::vpp_memory_format &mf) {
727     out << detail::space(detail::INTENT * 5, out, "Input Format = ")
728         << detail::FourCC2String(mf.get_input_format()) << std::endl;
729 
730     std::vector<uint32_t> fmts = mf.get_out_format();
731     out << detail::space(detail::INTENT * 5, out, "# of output formats = ") << fmts.size()
732         << std::endl;
733 
734     out << detail::space(detail::INTENT * 6, out, "color formats = ");
735     std::for_each(fmts.begin(), fmts.end(), [&](uint32_t fmt) {
736         out << detail::FourCC2String(fmt) << ", ";
737     });
738     out << "\b\b  " << std::endl;
739     return out;
740 }
741 
operator <<(std::ostream & out,const implementation_capabilities::vpp_memory & m)742 inline std::ostream &operator<<(std::ostream &out,
743                                 const implementation_capabilities::vpp_memory &m) {
744     out << detail::space(detail::INTENT * 4, out, "MemHandleType = ")
745         << detail::ResourceType2String(m.get_mem_type()) << std::endl;
746     out << detail::space(detail::INTENT * 4, out, "Frame size range = [")
747         << std::get<0>(m.get_min_size()) << "," << std::get<1>(m.get_min_size()) << "]:["
748         << std::get<0>(m.get_max_size()) << "," << std::get<1>(m.get_max_size()) << "]"
749         << std::endl;
750     std::vector<implementation_capabilities::vpp_memory_format> fmts = m.get_memory_formats();
751     out << detail::space(detail::INTENT * 4, out, "# of input formats = ") << fmts.size()
752         << std::endl;
753     std::for_each(fmts.begin(),
754                   fmts.end(),
755                   [&](implementation_capabilities::vpp_memory_format vpp_mf) {
756                       out << vpp_mf;
757                   });
758 
759     return out;
760 }
761 
operator <<(std::ostream & out,const implementation_capabilities::vpp_filter & f)762 inline std::ostream &operator<<(std::ostream &out,
763                                 const implementation_capabilities::vpp_filter &f) {
764     out << detail::space(detail::INTENT * 3, out, "FilterID = ")
765         << detail::FourCC2String(f.get_filter_id()) << std::endl;
766     out << detail::space(detail::INTENT * 3, out, "Max delay In Frames= ")
767         << f.get_max_delay_in_frames() << std::endl;
768 
769     std::vector<implementation_capabilities::vpp_memory> vm = f.get_memory_types();
770     out << detail::space(detail::INTENT * 3, out, "# of memory types = ") << vm.size() << std::endl;
771     std::for_each(vm.begin(), vm.end(), [&](implementation_capabilities::vpp_memory vpp_m) {
772         out << vpp_m;
773     });
774     return out;
775 }
776 
operator <<(std::ostream & out,const implementation_capabilities & f)777 inline std::ostream &operator<<(std::ostream &out, const implementation_capabilities &f) {
778     std::cout << "Implementation:" << std::endl;
779 
780     out << detail::space(detail::INTENT, out, "Impl    = ")
781         << detail::ImplType2String(f.caps_->Impl) << std::endl;
782     out << detail::space(detail::INTENT, out, "AccelerationMode = ")
783         << detail::AccelerationMode2String(f.caps_->AccelerationMode) << std::endl;
784 
785     out << detail::space(detail::INTENT, out, "API Version      = ") << f.caps_->ApiVersion.Major
786         << "." << f.caps_->ApiVersion.Minor << std::endl;
787     out << detail::space(detail::INTENT, out, "ImplName         = ") << f.caps_->ImplName
788         << std::endl;
789     out << detail::space(detail::INTENT, out, "License          = ") << f.caps_->License
790         << std::endl;
791     out << detail::space(detail::INTENT, out, "Keywords         = ") << f.caps_->Keywords
792         << std::endl;
793     out << detail::space(detail::INTENT, out, "VendorID         = ") << std::hex << std::showbase
794         << f.caps_->VendorID << std::endl;
795     out << detail::space(detail::INTENT, out, "VendorImplID     = ") << f.caps_->VendorImplID
796         << std::dec << std::endl;
797 
798     if (f.caps_->AccelerationModeDescription.NumAccelerationModes > 0) {
799         std::vector<std::string> accelmodes = f.get_accel_modes();
800         out << detail::space(detail::INTENT, out, "AccelerationModes:") << std::endl;
801         std::for_each(accelmodes.begin(), accelmodes.end(), [&](std::string mode) {
802             out << mode << std::endl;
803         });
804     }
805 
806     out << detail::space(detail::INTENT, out, "Target Device:") << std::endl;
807     out << detail::space(detail::INTENT * 2, out, "DeviceID        = ") << f.caps_->Dev.DeviceID
808         << std::endl;
809     out << detail::space(detail::INTENT * 2, out, "# of subdevices = ")
810         << f.caps_->Dev.NumSubDevices << std::endl;
811     for (int i = 0; i < f.caps_->Dev.NumSubDevices; i++) {
812         out << detail::space(detail::INTENT * 2, out, "SubdeviceID[") << i
813             << "] = " << f.caps_->Dev.SubDevices[i].SubDeviceID << std::endl;
814     }
815 
816     std::vector<implementation_capabilities::decoder> decoders = f.get_decoders();
817     out << detail::space(detail::INTENT, out, "Decoders:") << std::endl;
818     out << detail::space(detail::INTENT * 2, out, "# of decoders = ") << decoders.size()
819         << std::endl;
820 
821     std::for_each(decoders.begin(), decoders.end(), [&](implementation_capabilities::decoder dec) {
822         out << dec;
823     });
824 
825     std::vector<implementation_capabilities::encoder> encoders = f.get_encoders();
826     out << detail::space(detail::INTENT, out, "Encoders:") << std::endl;
827     out << detail::space(detail::INTENT * 2, out, "# of encoders = ") << encoders.size()
828         << std::endl;
829 
830     std::for_each(encoders.begin(), encoders.end(), [&](implementation_capabilities::encoder enc) {
831         out << enc;
832     });
833 
834     std::vector<implementation_capabilities::vpp_filter> filters = f.get_vpp_filters();
835     out << detail::space(detail::INTENT, out, "VPP Filters:") << std::endl;
836     out << detail::space(detail::INTENT * 2, out, "# of filters = ") << filters.size() << std::endl;
837 
838     std::for_each(filters.begin(), filters.end(), [&](implementation_capabilities::vpp_filter flt) {
839         out << flt;
840     });
841 
842     auto policies = f.get_pool_policies().policies();
843     out << detail::space(detail::INTENT, out, "Pool Policies:") << std::endl;
844     out << detail::space(detail::INTENT * 2, out, "# of policies = ") << policies.size() << std::endl;
845 
846     std::for_each(policies.begin(), policies.end(), [&](auto policy) {
847         out << policy;
848     });
849 
850     return out;
851 }
852 
operator <<(std::ostream & out,const implemented_functions & f)853 inline std::ostream &operator<<(std::ostream &out, const implemented_functions &f) {
854     std::cout << "Functions: " << std::endl;
855     auto names = f.get_functions_name();
856 
857     std::for_each(names.begin(), names.end(), [&](auto name) {
858         out << name << ", ";
859     });
860 
861     out << "\b\b  " << std::endl;
862     return out;
863 }
864 
operator <<(std::ostream & out,const implementation_path & f)865 inline std::ostream &operator<<(std::ostream &out, const implementation_path &f) {
866     std::cout << "Implementation path: " << f.get_path() << std::endl;
867     return out;
868 }
869 
870 } // namespace vpl
871 } // namespace oneapi
872