Ocean
USBLiveVideo.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_MEDIA_USB_USB_LIVE_VIDEO_H
9 #define META_OCEAN_MEDIA_USB_USB_LIVE_VIDEO_H
10 
11 #include "ocean/media/usb/USB.h"
13 
14 #include "ocean/base/Thread.h"
15 
16 #include "ocean/media/LiveVideo.h"
17 
19 
20 #ifdef OCEAN_PLATFORM_BUILD_ANDROID
22 
24 #endif
25 
26 #include <optional>
27 
28 namespace Ocean
29 {
30 
31 namespace Media
32 {
33 
34 namespace USB
35 {
36 
37 /**
38  * This class implements an live video class for USB devices.
39  * @ingroup mediausb
40  */
41 class OCEAN_MEDIA_USB_EXPORT USBLiveVideo final :
42  virtual public USBMedium,
43  virtual public LiveVideo,
44  protected Thread
45 {
46  friend class USBLibrary;
47 
48  /**
49  * This class implements a simple wrapper around Media::Android::VideoDecoder.
50  */
51  class OCEAN_MEDIA_USB_EXPORT VideoDecoder
52  {
53  protected:
54 
55  /**
56  * Definition of an unordered map mapping presentation times to timestamps.
57  */
58  using TimestampMap = std::unordered_map<int64_t, Timestamp>;
59 
60  public:
61 
62  /**
63  * Default constructor creating an invalid decoder.
64  */
65  VideoDecoder() = default;
66 
67  /**
68  * Default move constructor.
69  * @param videoDecoder The video decoder to be moved
70  */
71  VideoDecoder(VideoDecoder&& videoDecoder) = default;
72 
73  /**
74  * Creates a new decoder object and initializes and starts the decoder.
75  * @param mime The MIME type (Multipurpose Internet Mail Extensions) of the video to be decoded, e.g., "video/avc", "video/hevc", ...
76  * @param width The width of the video to be decoded, in pixel, with range [1, infinity)
77  * @param height The height of the video to be decoded, in pixel, with range [1, infinity)
78  * @see isValid()
79  */
80  VideoDecoder(const std::string& mime, const unsigned int width, const unsigned int height);
81 
82  /**
83  * Inserts a new sample to the video decoder.
84  * @param data The data of the sample, must be valid
85  * @param size The size of the sample, in bytes, with range [1, infinity)
86  * @param timestamp The capture timestamp of the sample, must be valid
87  * @return True, if the sample could be inserted
88  * @see popFrame().
89  */
90  bool pushSample(const void* data, const size_t size, const Timestamp& timestamp);
91 
92  /**
93  * Pops the next encoded frame from the video decoder.
94  * @return The encoded frame; an invalid frame if the decoder is not valid or if currently no decoded frame is waiting in the queue
95  * @see pushSample().
96  */
98 
99  /**
100  * Returns whether the video decoder is valid and can be used to decode video samples.
101  * @return True, if so; False, if the video decoder is not available on this platform or if the video decoder could not be initialized
102  */
103  bool isValid() const;
104 
105  /**
106  * Default move operator.
107  * @param videoDecoder The video decoder to be moved
108  * @return Reference to this object
109  */
110  VideoDecoder& operator=(VideoDecoder&& videoDecoder) = default;
111 
112  protected:
113 
114  /**
115  * Disabled copy constructor.
116  */
117  VideoDecoder(const VideoDecoder&) = delete;
118 
119  protected:
120 
121 #ifdef OCEAN_MEDIA_ANDROID_VIDEODECODER_AVAILABLE
122 
123  /// The actual video decoder.
125 
126 #endif // OCEAN_MEDIA_ANDROID_VIDEODECODER_AVAILABLE
127 
128  /// The counter for inserted media samples.
129  unsigned int sampleCounter_ = 0u;
130 
131  /// The map mapping presentation times to timestamps.
133  };
134 
135  public:
136 
137  /**
138  * Returns the supported stream types.
139  * @see LiveVideo::streamTypes().
140  */
142 
143  /**
144  * Returns the supported stream configurations for a given stream type.
145  * @see LiveVideo::streamConfigurations().
146  */
148 
149  /**
150  * Sets the preferred stream type.
151  * @see LiveVideo::setPreferredStreamType().
152  */
153  bool setPreferredStreamType(const StreamType streamType) override;
154 
155  /**
156  * Sets the preferred stream configuration.
157  * @see LiveVideo::setPreferredStreamConfiguration().
158  */
159  bool setPreferredStreamConfiguration(const StreamConfiguration& streamConfiguration) override;
160 
161  /**
162  * Returns the current exposure duration of this device.
163  * @see LiveVideo::exposureDuration().
164  */
165  double exposureDuration(double* minDuration = nullptr, double* maxDuration = nullptr, ControlMode* exposureMode = nullptr) const override;
166 
167  /**
168  * Sets the exposure duration of this device.
169  * @see LiveVideo::setExposureDuration().
170  */
171  bool setExposureDuration(const double duration) override;
172 
173  /**
174  * Returns the current focus of this device.
175  * @see LiveVideo::focus().
176  */
177  float focus(ControlMode* focusMode = nullptr) const override;
178 
179  /**
180  * Sets the focus of this device.
181  @see LiveVideo::setFocus().
182  */
183  bool setFocus(const float position) override;
184 
185  /**
186  * Returns whether the medium is started currently.
187  * @see Medium::isStarted().
188  */
189  bool isStarted() const override;
190 
191  /**
192  * Returns the start timestamp.
193  * @see FiniteMedium::startTimestamp().
194  */
195  Timestamp startTimestamp() const override;
196 
197  /**
198  * Returns the pause timestamp.
199  * @see FiniteMedium::pauseTimestamp().
200  */
201  Timestamp pauseTimestamp() const override;
202 
203  /**
204  * Returns the stop timestamp.
205  * @see FiniteMedium::stopTimestamp().
206  */
207  Timestamp stopTimestamp() const override;
208 
209  protected:
210 
211  /**
212  * Creates a new medium by a given url.
213  * @param url Url of the medium
214  * @param deviceName The name of the USB device
215  */
216  explicit USBLiveVideo(const std::string& url, const std::string& deviceName);
217 
218  /**
219  * Destructs the live video object.
220  */
221  ~USBLiveVideo() override;
222 
223  /**
224  * Starts the medium.
225  * @see Medium::start().
226  */
227  bool start() override;
228 
229  /**
230  * Pauses the medium.
231  * @see Medium::pause():
232  */
233  bool pause() override;
234 
235  /**
236  * Stops the medium.
237  * @see Medium::stop().
238  */
239  bool stop() override;
240 
241  /**
242  * Internal start function actually starting the USB video stream.
243  * @return True, if succeeded
244  */
246 
247  /**
248  * Internal stop function actually stopping the USB video stream.
249  * @return True, if succeeded
250  */
251  bool stopInternal();
252 
253  /**
254  * Opens the USB device.
255  * For Android platforms: Ensure that permission has been grated before opening the device.
256  * @param deviceName The name of the USB device to open
257  * @return True, if succeeded
258  */
259  bool openDevice(const std::string& deviceName);
260 
261  /**
262  * Closes the USB device.
263  * @return True, if succeeded
264  */
265  bool closeDevice();
266 
267  /**
268  * Event function for device permission events.
269  * @param deviceName The name of the USB device for which the event has been triggered, will be valid
270  * @param permissionGranted True, if the permission was granted; False, if the permission has been denied
271  */
272  void onPermission(const std::string& deviceName, const bool permissionGranted);
273 
274  /**
275  * The thread function of this medium in which frame processing is handled.
276  */
277  void threadRun() override;
278 
279  /**
280  * Ensures that the current exposure mode is initialized.
281  * @return True, if succeeded
282  */
284 
285  /**
286  * Ensures that the current focus mode is initialized.
287  * @return True, if succeeded
288  */
290 
291  /**
292  * Processes a sample from an uncompressed video stream.
293  * @param width The width of the uncompressed frame in pixel, with range [1, infinity)
294  * @param height The height of the uncompressed frame in pixel, with range [1, infinity)
295  * @param pixelFormat The pixel format of the uncompressed frame, must be valid
296  * @param data The actual frame data, must be valid
297  * @param size The size of the frame data, in bytes, with range [1, infinity)
298  * @return The resulting frame, invalid in case of an error
299  */
300  static Frame processUncompressedSample(const unsigned int width, const unsigned int height, const FrameType::PixelFormat pixelFormat, const void* data, const size_t size);
301 
302  /**
303  * Processes a sample from an MJPEG stream.
304  * @param width The width of the decoded frame in pixel, with range [1, infinity)
305  * @param height The height of the decoded frame in pixel, with range [1, infinity)
306  * @param data The data holding the MJPEG data, must be valid
307  * @param size The size of the MJPEG data, in bytes, with range [1, infinity)
308  * @return The resulting frame, invalid in case of an error
309  */
310  static Frame processMjpegSample(const unsigned int width, const unsigned int height, const void* data, const size_t size);
311 
312  /**
313  * Translates a LiveVideo stream type to the corresponding USB device stream type.
314  * @param streamType The live video stream type to be translated
315  * @return The translated USB device stream type, DST_INVALID if the LiveVideo stream type is invalid or unknown
316  */
318 
319  /**
320  * Translates a LiveVideo codec type to the corresponding USB video encoding format.
321  * @param codecType The live video codec type to be translated
322  * @return The translated USB video encoding format, EF_INVALID if the LiveVideo codec type is invalid or unknown
323  */
325 
326  /**
327  * Translates a USB video encoding format to the corresponding LiveVideo codec type.
328  * @param encodingFormat The USB video encoding format to be translated
329  * @return The translated LiveVideo codec type, CT_INVALID if the USB video encoding format is invalid or unknown
330  */
332 
333  /**
334  * Translates a USB video encoding format to the corresponding MIME type.
335  * @param encodingFormat The USB video encoding format to be translated
336  * @return The translated MIME type, empty if the USB video encoding format is invalid or unknown
337  */
339 
340  protected:
341 
342  /// The name of the USB device.
343  std::string deviceName_;
344 
345  /// The preferred stream type.
346  StreamType preferredStreamType_ = ST_INVALID;
347 
348  /// The preferred codec type.
349  CodecType preferredCodecType_ = CT_INVALID;
350 
351  /// The actual USB video device which will be used.
353 
354  /// 1 if the medium has permission to access the USB device, -1 if permission was denied, 0 if the permission is not yet decided.
355  std::atomic_int hasPermission_ = 0;
356 
357  /// Start timestamp.
359 
360  /// Pause timestamp.
362 
363  /// Stop timestamp.
365 
366  /// The live video's exposure mode.
367  mutable std::optional<ControlMode> exposureMode_;
368 
369  /// The live video's exposure duration in case the duration is fixed, in seconds, -1 if not fixed, minValue() if not yet known.
370  mutable double fixedExposureDuration_ = NumericD::minValue();
371 
372  /// The live video's minimal exposure duration, in seconds, -1 if not known.
373  mutable double minExposureDuration_ = -1.0;
374 
375  /// The live video's maximal exposure duration, in seconds, -1 if not known.
376  mutable double maxExposureDuration_ = -1.0;
377 
378  /// The UVC auto exposure mode to be used, -1 not yet known, 0 if not supported.
379  uint8_t videoDeviceAutoExposureMode_ = uint8_t(-1);
380 
381  /// The live video's focus mode.
382  mutable std::optional<ControlMode> focusMode_;
383 
384  /// The live video's focus in case the focus is fixed, -1 if not fixed, minValue() if not yet known.
385  mutable float fixedFocus_ = NumericF::minValue();
386 
387  /// The live video's minimal focus, -1 if not known.
388  mutable float minFocus_ = -1.0f;
389 
390  /// The live video's maximal focus, -1 if not known.
391  mutable float maxFocus_ = -1.0f;
392 
393 #ifdef OCEAN_PLATFORM_BUILD_ANDROID
394 
395  /// The permission request object for the USB device.
397 
398  /// True, if the device needs to be started (out of the thread function).
399  std::atomic_bool delayedStart_ = false;
400 
401  /// True, if the device needs to be stopped (out of the thread function).
402  std::atomic_bool delayedStop_ = false;
403 
404 #endif // OCEAN_PLATFORM_BUILD_ANDROID
405 };
406 
407 }
408 
409 }
410 
411 }
412 
413 #endif // META_OCEAN_MEDIA_USB_USB_LIVE_VIDEO_H
This class implements Ocean's image class.
Definition: Frame.h:1792
PixelFormat
Definition of all pixel formats available in the Ocean framework.
Definition: Frame.h:183
This class implements a simple video decoder for Android using encoded media samples from memory as i...
Definition: VideoDecoder.h:90
This class holds the relevant information describing a video stream configuration.
Definition: LiveVideo.h:92
This class is the base class for all live videos.
Definition: LiveVideo.h:38
CodecType
Definition of individual codec types.
Definition: LiveVideo.h:79
StreamType
Definition of individual stream types.
Definition: LiveVideo.h:59
ControlMode
Definition of individual control modes.
Definition: LiveVideo.h:46
std::vector< StreamConfiguration > StreamConfigurations
Definition of a vector holding stream configurations.
Definition: LiveVideo.h:148
std::vector< StreamType > StreamTypes
Definition of a vector holding stream types.
Definition: LiveVideo.h:73
This class implements the USB library.
Definition: USBLibrary.h:34
This class implements a simple wrapper around Media::Android::VideoDecoder.
Definition: USBLiveVideo.h:52
bool isValid() const
Returns whether the video decoder is valid and can be used to decode video samples.
TimestampMap timestampMap_
The map mapping presentation times to timestamps.
Definition: USBLiveVideo.h:132
Frame popFrame()
Pops the next encoded frame from the video decoder.
VideoDecoder & operator=(VideoDecoder &&videoDecoder)=default
Default move operator.
VideoDecoder(const std::string &mime, const unsigned int width, const unsigned int height)
Creates a new decoder object and initializes and starts the decoder.
VideoDecoder(const VideoDecoder &)=delete
Disabled copy constructor.
Media::Android::VideoDecoder videoDecoder_
The actual video decoder.
Definition: USBLiveVideo.h:124
VideoDecoder()=default
Default constructor creating an invalid decoder.
std::unordered_map< int64_t, Timestamp > TimestampMap
Definition of an unordered map mapping presentation times to timestamps.
Definition: USBLiveVideo.h:58
VideoDecoder(VideoDecoder &&videoDecoder)=default
Default move constructor.
bool pushSample(const void *data, const size_t size, const Timestamp &timestamp)
Inserts a new sample to the video decoder.
This class implements an live video class for USB devices.
Definition: USBLiveVideo.h:45
bool setPreferredStreamType(const StreamType streamType) override
Sets the preferred stream type.
bool setExposureDuration(const double duration) override
Sets the exposure duration of this device.
Timestamp stopTimestamp() const override
Returns the stop timestamp.
bool stopInternal()
Internal stop function actually stopping the USB video stream.
Timestamp stopTimestamp_
Stop timestamp.
Definition: USBLiveVideo.h:364
bool setFocus(const float position) override
Sets the focus of this device.
std::string deviceName_
The name of the USB device.
Definition: USBLiveVideo.h:343
System::USB::Android::OceanUSBManager::ScopedPermissionSubscription permissionSubscription_
The permission request object for the USB device.
Definition: USBLiveVideo.h:396
Timestamp startTimestamp() const override
Returns the start timestamp.
bool openDevice(const std::string &deviceName)
Opens the USB device.
static CodecType translateEncodingFormat(const System::USB::Video::VSFrameBasedVideoFormatDescriptor::EncodingFormat encodingFormat)
Translates a USB video encoding format to the corresponding LiveVideo codec type.
bool pause() override
Pauses the medium.
std::optional< ControlMode > focusMode_
The live video's focus mode.
Definition: USBLiveVideo.h:382
USBLiveVideo(const std::string &url, const std::string &deviceName)
Creates a new medium by a given url.
void threadRun() override
The thread function of this medium in which frame processing is handled.
Timestamp pauseTimestamp() const override
Returns the pause timestamp.
static Frame processMjpegSample(const unsigned int width, const unsigned int height, const void *data, const size_t size)
Processes a sample from an MJPEG stream.
void onPermission(const std::string &deviceName, const bool permissionGranted)
Event function for device permission events.
static System::USB::Video::VideoDevice::DeviceStreamType translateStreamType(const StreamType streamType)
Translates a LiveVideo stream type to the corresponding USB device stream type.
std::optional< ControlMode > exposureMode_
The live video's exposure mode.
Definition: USBLiveVideo.h:367
static std::string mimeFromEncodingFormat(const System::USB::Video::VSFrameBasedVideoFormatDescriptor::EncodingFormat encodingFormat)
Translates a USB video encoding format to the corresponding MIME type.
static System::USB::Video::VSFrameBasedVideoFormatDescriptor::EncodingFormat translateCodecType(const CodecType codecType)
Translates a LiveVideo codec type to the corresponding USB video encoding format.
Timestamp startTimestamp_
Start timestamp.
Definition: USBLiveVideo.h:358
StreamConfigurations supportedStreamConfigurations(const StreamType streamType) const override
Returns the supported stream configurations for a given stream type.
~USBLiveVideo() override
Destructs the live video object.
bool setPreferredStreamConfiguration(const StreamConfiguration &streamConfiguration) override
Sets the preferred stream configuration.
System::USB::Video::SharedVideoDevice videoDevice_
The actual USB video device which will be used.
Definition: USBLiveVideo.h:352
Timestamp pauseTimestamp_
Pause timestamp.
Definition: USBLiveVideo.h:361
bool stop() override
Stops the medium.
bool start() override
Starts the medium.
bool ensureInitializedFocusMode() const
Ensures that the current focus mode is initialized.
static Frame processUncompressedSample(const unsigned int width, const unsigned int height, const FrameType::PixelFormat pixelFormat, const void *data, const size_t size)
Processes a sample from an uncompressed video stream.
float focus(ControlMode *focusMode=nullptr) const override
Returns the current focus of this device.
bool closeDevice()
Closes the USB device.
bool isStarted() const override
Returns whether the medium is started currently.
double exposureDuration(double *minDuration=nullptr, double *maxDuration=nullptr, ControlMode *exposureMode=nullptr) const override
Returns the current exposure duration of this device.
bool startInternal()
Internal start function actually starting the USB video stream.
bool ensureInitializedExposureMode() const
Ensures that the current exposure mode is initialized.
StreamTypes supportedStreamTypes() const override
Returns the supported stream types.
This class implements the base class for all Medium objects in the USB library.
Definition: USBMedium.h:29
static constexpr T minValue()
Returns the min scalar value.
Definition: Numeric.h:3250
EncodingFormat
Definition of individual encoding formats.
Definition: VSDescriptor.h:498
DeviceStreamType
Definition of individual USB UVC device stream types.
Definition: VideoDevice.h:59
This class implements a thread.
Definition: Thread.h:115
This class implements a timestamp.
Definition: Timestamp.h:36
std::shared_ptr< VideoDevice > SharedVideoDevice
Definition of a shared pointer holding a VideoDevice.
Definition: VideoDevice.h:39
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15