LibavIntrospection.hpp
1 #pragma once
2 
3 #include <Media/Libav.hpp>
4 #if SCORE_HAS_LIBAV
5 extern "C" {
6 #include <libavcodec/avcodec.h>
7 #include <libavformat/avformat.h>
8 #include <libavutil/pixdesc.h>
9 }
10 
11 namespace Gfx
12 {
13 struct ACodecInfo
14 {
15  explicit ACodecInfo(const AVCodec* codec) noexcept
16  : codec{codec}
17  {
18  }
19  const AVCodec* codec{};
20 };
21 struct VCodecInfo
22 {
23  explicit VCodecInfo(const AVCodec* codec) noexcept
24  : codec{codec}
25  {
26  }
27  const AVCodec* codec{};
28 };
30 {
31  explicit DemuxerInfo(const AVInputFormat* format) noexcept
32  : format{format}
33  {
34  }
35  const AVInputFormat* format{};
36 };
37 struct MuxerInfo
38 {
39  explicit MuxerInfo(const AVOutputFormat* format) noexcept
40  : format{format}
41  {
42  }
43  const AVOutputFormat* format{};
44  ossia::small_vector<const ACodecInfo*, 4> acodecs;
45  ossia::small_vector<const VCodecInfo*, 4> vcodecs;
46 };
47 
49 {
50  std::vector<VCodecInfo> vcodecs;
51  std::vector<ACodecInfo> acodecs;
52 
53  std::vector<MuxerInfo> muxers;
54  std::vector<DemuxerInfo> demuxers;
55 
57  {
58  vcodecs.reserve(500);
59  acodecs.reserve(350);
60  muxers.reserve(200);
61  demuxers.reserve(200);
62 
63  void* opaque = nullptr;
64  while(auto codec = av_codec_iterate(&opaque))
65  {
66  if(!av_codec_is_encoder(codec))
67  continue;
68 
69  if(codec->type == AVMediaType::AVMEDIA_TYPE_AUDIO)
70  acodecs.emplace_back(codec);
71  if(codec->type == AVMediaType::AVMEDIA_TYPE_VIDEO)
72  vcodecs.emplace_back(codec);
73  }
74 
75  opaque = nullptr;
76  while(auto format = av_muxer_iterate(&opaque))
77  {
78  MuxerInfo fmt{format};
79  for(const auto& codec : vcodecs)
80  {
81  if(avformat_query_codec(format, codec.codec->id, FF_COMPLIANCE_STRICT) == 1)
82  {
83  fmt.vcodecs.push_back(&codec);
84  }
85  }
86  for(const auto& codec : acodecs)
87  {
88  if(avformat_query_codec(format, codec.codec->id, FF_COMPLIANCE_STRICT) == 1)
89  {
90  fmt.acodecs.push_back(&codec);
91  }
92  }
93  if(fmt.vcodecs.empty() && fmt.acodecs.empty())
94  continue;
95  muxers.push_back(std::move(fmt));
96  }
97 
98  opaque = nullptr;
99  while(auto format = av_demuxer_iterate(&opaque))
100  {
101  demuxers.push_back(DemuxerInfo{format});
102  }
103  }
104 
105  const MuxerInfo*
106  findMuxer(const QString& name, const QString& long_name) const noexcept
107  {
108  for(auto& obj : muxers)
109  {
110  if(obj.format->long_name)
111  {
112  if(obj.format->name == name && obj.format->long_name == long_name)
113  return &obj;
114  }
115  }
116  for(auto& obj : muxers)
117  {
118  if(obj.format->name == name)
119  return &obj;
120  }
121  return nullptr;
122  }
123 
124  const DemuxerInfo*
125  findDemuxer(const QString& name, const QString& long_name) const noexcept
126  {
127  for(auto& obj : demuxers)
128  {
129  if(obj.format->long_name)
130  {
131  if(obj.format->name == name && obj.format->long_name == long_name)
132  return &obj;
133  }
134  }
135  for(auto& obj : demuxers)
136  {
137  if(obj.format->name == name)
138  return &obj;
139  }
140  return nullptr;
141  }
142 
143  const VCodecInfo*
144  findVideoCodec(const QString& name, const QString& long_name) const noexcept
145  {
146  for(auto& obj : vcodecs)
147  {
148  if(obj.codec->long_name)
149  {
150  if(obj.codec->name == name && obj.codec->long_name == long_name)
151  return &obj;
152  }
153  }
154  for(auto& obj : vcodecs)
155  {
156  if(obj.codec->name == name)
157  return &obj;
158  }
159  return nullptr;
160  }
161 
162  const ACodecInfo*
163  findAudioCodec(const QString& name, const QString& long_name) const noexcept
164  {
165  for(auto& obj : acodecs)
166  {
167  if(obj.codec->long_name)
168  {
169  if(obj.codec->name == name && obj.codec->long_name == long_name)
170  return &obj;
171  }
172  }
173  for(auto& obj : acodecs)
174  {
175  if(obj.codec->name == name)
176  return &obj;
177  }
178  return nullptr;
179  }
180 
181  static const LibavIntrospection& instance() noexcept
182  {
183  static const LibavIntrospection p;
184  return p;
185  }
186 };
187 
188 }
189 #endif
Binds the rendering pipeline to ossia processes.
Definition: CameraDevice.cpp:28
Definition: LibavIntrospection.hpp:14
Definition: LibavIntrospection.hpp:30
Definition: LibavIntrospection.hpp:49
Definition: LibavIntrospection.hpp:38
Definition: LibavIntrospection.hpp:22