1 /*
2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef WEBRTC_MODULES_INTERFACE_VIDEO_CODING_H_
12 #define WEBRTC_MODULES_INTERFACE_VIDEO_CODING_H_
13 
14 #if defined(WEBRTC_WIN)
15 // This is a workaround on Windows due to the fact that some Windows
16 // headers define CreateEvent as a macro to either CreateEventW or CreateEventA.
17 // This can cause problems since we use that name as well and could
18 // declare them as one thing here whereas in another place a windows header
19 // may have been included and then implementing CreateEvent() causes compilation
20 // errors.  So for consistency, we include the main windows header here.
21 #include <windows.h>
22 #endif
23 
24 #include "webrtc/common_video/interface/i420_video_frame.h"
25 #include "webrtc/modules/interface/module.h"
26 #include "webrtc/modules/interface/module_common_types.h"
27 #include "webrtc/modules/video_coding/main/interface/video_coding_defines.h"
28 #include "webrtc/system_wrappers/interface/event_wrapper.h"
29 
30 namespace webrtc
31 {
32 
33 class Clock;
34 class EncodedImageCallback;
35 class VideoEncoder;
36 class VideoDecoder;
37 struct CodecSpecificInfo;
38 
39 class EventFactory {
40  public:
~EventFactory()41   virtual ~EventFactory() {}
42 
43   virtual EventWrapper* CreateEvent() = 0;
44 };
45 
46 class EventFactoryImpl : public EventFactory {
47  public:
~EventFactoryImpl()48   virtual ~EventFactoryImpl() {}
49 
CreateEvent()50   virtual EventWrapper* CreateEvent() {
51     return EventWrapper::Create();
52   }
53 };
54 
55 // Used to indicate which decode with errors mode should be used.
56 enum VCMDecodeErrorMode {
57   kNoErrors,                // Never decode with errors. Video will freeze
58                             // if nack is disabled.
59   kSelectiveErrors,         // Frames that are determined decodable in
60                             // VCMSessionInfo may be decoded with missing
61                             // packets. As not all incomplete frames will be
62                             // decodable, video will freeze if nack is disabled.
63   kWithErrors               // Release frames as needed. Errors may be
64                             // introduced as some encoded frames may not be
65                             // complete.
66 };
67 
68 class VideoCodingModule : public Module
69 {
70 public:
71     enum SenderNackMode {
72         kNackNone,
73         kNackAll,
74         kNackSelective
75     };
76 
77     enum ReceiverRobustness {
78         kNone,
79         kHardNack,
80         kSoftNack,
81         kReferenceSelection
82     };
83 
84     static VideoCodingModule* Create(
85         VideoEncoderRateObserver* encoder_rate_observer);
86 
87     static VideoCodingModule* Create(Clock* clock, EventFactory* event_factory);
88 
89     static void Destroy(VideoCodingModule* module);
90 
91     // Get number of supported codecs
92     //
93     // Return value     : Number of supported codecs
94     static uint8_t NumberOfCodecs();
95 
96     // Get supported codec settings with using id
97     //
98     // Input:
99     //      - listId         : Id or index of the codec to look up
100     //      - codec          : Memory where the codec settings will be stored
101     //
102     // Return value     : VCM_OK,              on success
103     //                    VCM_PARAMETER_ERROR  if codec not supported or id too high
104     static int32_t Codec(const uint8_t listId, VideoCodec* codec);
105 
106     // Get supported codec settings using codec type
107     //
108     // Input:
109     //      - codecType      : The codec type to get settings for
110     //      - codec          : Memory where the codec settings will be stored
111     //
112     // Return value     : VCM_OK,              on success
113     //                    VCM_PARAMETER_ERROR  if codec not supported
114     static int32_t Codec(VideoCodecType codecType, VideoCodec* codec);
115 
116     /*
117     *   Sender
118     */
119 
120     // Any encoder-related state of VCM will be initialized to the
121     // same state as when the VCM was created. This will not interrupt
122     // or effect decoding functionality of VCM. VCM will lose all the
123     // encoding-related settings by calling this function.
124     // For instance, a send codec has to be registered again.
125     //
126     // NOTE: Must be called on the thread that constructed the VCM instance.
127     //
128     // Return value      : VCM_OK, on success.
129     //                     < 0,         on error.
130     virtual int32_t InitializeSender() = 0;
131 
132     // Registers a codec to be used for encoding. Calling this
133     // API multiple times overwrites any previously registered codecs.
134     //
135     // NOTE: Must be called on the thread that constructed the VCM instance.
136     //
137     // Input:
138     //      - sendCodec      : Settings for the codec to be registered.
139     //      - numberOfCores  : The number of cores the codec is allowed
140     //                         to use.
141     //      - maxPayloadSize : The maximum size each payload is allowed
142     //                                to have. Usually MTU - overhead.
143     //
144     // Return value      : VCM_OK, on success.
145     //                     < 0,         on error.
146     virtual int32_t RegisterSendCodec(const VideoCodec* sendCodec,
147                                             uint32_t numberOfCores,
148                                             uint32_t maxPayloadSize) = 0;
149 
150     // Get the current send codec in use.
151     //
152     // If a codec has not been set yet, the |id| property of the return value
153     // will be 0 and |name| empty.
154     //
155     // NOTE: This method intentionally does not hold locks and minimizes data
156     // copying.  It must be called on the thread where the VCM was constructed.
157     virtual const VideoCodec& GetSendCodec() const = 0;
158 
159     // DEPRECATED: Use GetSendCodec() instead.
160     //
161     // API to get the current send codec in use.
162     //
163     // Input:
164     //      - currentSendCodec : Address where the sendCodec will be written.
165     //
166     // Return value      : VCM_OK, on success.
167     //                     < 0,         on error.
168     //
169     // NOTE: The returned codec information is not guaranteed to be current when
170     // the call returns.  This method acquires a lock that is aligned with
171     // video encoding, so it should be assumed to be allowed to block for
172     // several milliseconds.
173     virtual int32_t SendCodec(VideoCodec* currentSendCodec) const = 0;
174 
175     // DEPRECATED: Use GetSendCodec() instead.
176     //
177     // API to get the current send codec type
178     //
179     // Return value      : Codec type, on success.
180     //                     kVideoCodecUnknown, on error or if no send codec is set
181     // NOTE: Same notes apply as for SendCodec() above.
182     virtual VideoCodecType SendCodec() const = 0;
183 
184     // Register an external encoder object. This can not be used together with
185     // external decoder callbacks.
186     //
187     // Input:
188     //      - externalEncoder : Encoder object to be used for encoding frames inserted
189     //                          with the AddVideoFrame API.
190     //      - payloadType     : The payload type bound which this encoder is bound to.
191     //
192     // Return value      : VCM_OK, on success.
193     //                     < 0,         on error.
194     virtual int32_t RegisterExternalEncoder(VideoEncoder* externalEncoder,
195                                             uint8_t payloadType,
196                                             bool internalSource = false) = 0;
197 
198     // API to get codec config parameters to be sent out-of-band to a receiver.
199     //
200     // Input:
201     //      - buffer          : Memory where the codec config parameters should be written.
202     //      - size            : Size of the memory available.
203     //
204     // Return value      : Number of bytes written, on success.
205     //                     < 0,                     on error.
206     virtual int32_t CodecConfigParameters(uint8_t* buffer, int32_t size) = 0;
207 
208     // API to get currently configured encoder target bitrate in bits/s.
209     //
210     // Return value      : 0,   on success.
211     //                     < 0, on error.
212     virtual int Bitrate(unsigned int* bitrate) const = 0;
213 
214     // API to get currently configured encoder target frame rate.
215     //
216     // Return value      : 0,   on success.
217     //                     < 0, on error.
218     virtual int FrameRate(unsigned int* framerate) const = 0;
219 
220     // Sets the parameters describing the send channel. These parameters are inputs to the
221     // Media Optimization inside the VCM and also specifies the target bit rate for the
222     // encoder. Bit rate used by NACK should already be compensated for by the user.
223     //
224     // Input:
225     //      - target_bitrate        : The target bitrate for VCM in bits/s.
226     //      - lossRate              : Fractions of lost packets the past second.
227     //                                (loss rate in percent = 100 * packetLoss / 255)
228     //      - rtt                   : Current round-trip time in ms.
229     //
230     // Return value      : VCM_OK, on success.
231     //                     < 0,         on error.
232     virtual int32_t SetChannelParameters(uint32_t target_bitrate,
233                                          uint8_t lossRate,
234                                          int64_t rtt) = 0;
235 
236     // Sets the parameters describing the receive channel. These parameters are inputs to the
237     // Media Optimization inside the VCM.
238     //
239     // Input:
240     //      - rtt                   : Current round-trip time in ms.
241     //                                with the most amount available bandwidth in a conference
242     //                                scenario
243     //
244     // Return value      : VCM_OK, on success.
245     //                     < 0,         on error.
246     virtual int32_t SetReceiveChannelParameters(int64_t rtt) = 0;
247 
248     // Register a transport callback which will be called to deliver the encoded data and
249     // side information.
250     //
251     // Input:
252     //      - transport  : The callback object to register.
253     //
254     // Return value      : VCM_OK, on success.
255     //                     < 0,         on error.
256     virtual int32_t RegisterTransportCallback(VCMPacketizationCallback* transport) = 0;
257 
258     // Register video output information callback which will be called to deliver information
259     // about the video stream produced by the encoder, for instance the average frame rate and
260     // bit rate.
261     //
262     // Input:
263     //      - outputInformation  : The callback object to register.
264     //
265     // Return value      : VCM_OK, on success.
266     //                     < 0,         on error.
267     virtual int32_t RegisterSendStatisticsCallback(
268                                      VCMSendStatisticsCallback* sendStats) = 0;
269 
270     // Register a video quality settings callback which will be called when
271     // frame rate/dimensions need to be updated for video quality optimization
272     //
273     // Input:
274     //      - videoQMSettings  : The callback object to register.
275     //
276     // Return value      : VCM_OK, on success.
277     //                     < 0,         on error
278     virtual int32_t RegisterVideoQMCallback(VCMQMSettingsCallback* videoQMSettings) = 0;
279 
280     // Register a video protection callback which will be called to deliver
281     // the requested FEC rate and NACK status (on/off).
282     //
283     // Input:
284     //      - protection  : The callback object to register.
285     //
286     // Return value      : VCM_OK, on success.
287     //                     < 0,         on error.
288     virtual int32_t RegisterProtectionCallback(VCMProtectionCallback* protection) = 0;
289 
290     // Enable or disable a video protection method.
291     //
292     // Input:
293     //      - videoProtection  : The method to enable or disable.
294     //      - enable           : True if the method should be enabled, false if
295     //                           it should be disabled.
296     //
297     // Return value      : VCM_OK, on success.
298     //                     < 0,         on error.
299     virtual int32_t SetVideoProtection(VCMVideoProtection videoProtection,
300                                        bool enable) = 0;
301 
302     // Add one raw video frame to the encoder. This function does all the necessary
303     // processing, then decides what frame type to encode, or if the frame should be
304     // dropped. If the frame should be encoded it passes the frame to the encoder
305     // before it returns.
306     //
307     // Input:
308     //      - videoFrame        : Video frame to encode.
309     //      - codecSpecificInfo : Extra codec information, e.g., pre-parsed in-band signaling.
310     //
311     // Return value      : VCM_OK, on success.
312     //                     < 0,         on error.
313     virtual int32_t AddVideoFrame(
314         const I420VideoFrame& videoFrame,
315         const VideoContentMetrics* contentMetrics = NULL,
316         const CodecSpecificInfo* codecSpecificInfo = NULL) = 0;
317 
318     // Next frame encoded should be an intra frame (keyframe).
319     //
320     // Return value      : VCM_OK, on success.
321     //                     < 0,         on error.
322     virtual int32_t IntraFrameRequest(int stream_index) = 0;
323 
324     // Frame Dropper enable. Can be used to disable the frame dropping when the encoder
325     // over-uses its bit rate. This API is designed to be used when the encoded frames
326     // are supposed to be stored to an AVI file, or when the I420 codec is used and the
327     // target bit rate shouldn't affect the frame rate.
328     //
329     // Input:
330     //      - enable            : True to enable the setting, false to disable it.
331     //
332     // Return value      : VCM_OK, on success.
333     //                     < 0,         on error.
334     virtual int32_t EnableFrameDropper(bool enable) = 0;
335 
336     // Sent frame counters
337     virtual int32_t SentFrameCount(VCMFrameCount& frameCount) const = 0;
338 
339     /*
340     *   Receiver
341     */
342 
343     // The receiver state of the VCM will be initialized to the
344     // same state as when the VCM was created. This will not interrupt
345     // or effect the send side functionality of VCM. VCM will lose all the
346     // decoding-related settings by calling this function. All frames
347     // inside the jitter buffer are flushed and the delay is reset.
348     // For instance, a receive codec has to be registered again.
349     //
350     // Return value      : VCM_OK, on success.
351     //                     < 0,         on error.
352     virtual int32_t InitializeReceiver() = 0;
353 
354     // Register possible receive codecs, can be called multiple times for different codecs.
355     // The module will automatically switch between registered codecs depending on the
356     // payload type of incoming frames. The actual decoder will be created when needed.
357     //
358     // Input:
359     //      - receiveCodec      : Settings for the codec to be registered.
360     //      - numberOfCores     : Number of CPU cores that the decoder is allowed to use.
361     //      - requireKeyFrame   : Set this to true if you don't want any delta frames
362     //                            to be decoded until the first key frame has been decoded.
363     //
364     // Return value      : VCM_OK, on success.
365     //                     < 0,         on error.
366     virtual int32_t RegisterReceiveCodec(const VideoCodec* receiveCodec,
367                                          int32_t numberOfCores,
368                                          bool requireKeyFrame = false) = 0;
369 
370     // Register an externally defined decoder/renderer object. Can be a decoder only or a
371     // decoder coupled with a renderer. Note that RegisterReceiveCodec must be called to
372     // be used for decoding incoming streams.
373     //
374     // Input:
375     //      - externalDecoder        : The external decoder/renderer object.
376     //      - payloadType            : The payload type which this decoder should be
377     //                                 registered to.
378     //      - internalRenderTiming   : True if the internal renderer (if any) of the decoder
379     //                                 object can make sure to render at a given time in ms.
380     //
381     // Return value      : VCM_OK, on success.
382     //                     < 0,         on error.
383     virtual int32_t RegisterExternalDecoder(VideoDecoder* externalDecoder,
384                                             uint8_t payloadType,
385                                             bool internalRenderTiming) = 0;
386 
387     // Register a receive callback. Will be called whenever there is a new frame ready
388     // for rendering.
389     //
390     // Input:
391     //      - receiveCallback        : The callback object to be used by the module when a
392     //                                 frame is ready for rendering.
393     //                                 De-register with a NULL pointer.
394     //
395     // Return value      : VCM_OK, on success.
396     //                     < 0,         on error.
397     virtual int32_t RegisterReceiveCallback(VCMReceiveCallback* receiveCallback) = 0;
398 
399     // Register a receive statistics callback which will be called to deliver information
400     // about the video stream received by the receiving side of the VCM, for instance the
401     // average frame rate and bit rate.
402     //
403     // Input:
404     //      - receiveStats  : The callback object to register.
405     //
406     // Return value      : VCM_OK, on success.
407     //                     < 0,         on error.
408     virtual int32_t RegisterReceiveStatisticsCallback(
409                                VCMReceiveStatisticsCallback* receiveStats) = 0;
410 
411     // Register a decoder timing callback which will be called to deliver
412     // information about the timing of the decoder in the receiving side of the
413     // VCM, for instance the current and maximum frame decode latency.
414     //
415     // Input:
416     //      - decoderTiming  : The callback object to register.
417     //
418     // Return value      : VCM_OK, on success.
419     //                     < 0,         on error.
420     virtual int32_t RegisterDecoderTimingCallback(
421         VCMDecoderTimingCallback* decoderTiming) = 0;
422 
423     // Register a frame type request callback. This callback will be called when the
424     // module needs to request specific frame types from the send side.
425     //
426     // Input:
427     //      - frameTypeCallback      : The callback object to be used by the module when
428     //                                 requesting a specific type of frame from the send side.
429     //                                 De-register with a NULL pointer.
430     //
431     // Return value      : VCM_OK, on success.
432     //                     < 0,         on error.
433     virtual int32_t RegisterFrameTypeCallback(
434                                   VCMFrameTypeCallback* frameTypeCallback) = 0;
435 
436     // Registers a callback which is called whenever the receive side of the VCM
437     // encounters holes in the packet sequence and needs packets to be retransmitted.
438     //
439     // Input:
440     //              - callback      : The callback to be registered in the VCM.
441     //
442     // Return value     : VCM_OK,     on success.
443     //                    <0,              on error.
444     virtual int32_t RegisterPacketRequestCallback(
445                                         VCMPacketRequestCallback* callback) = 0;
446 
447     // Register a receive state change callback. This callback will be called when the
448     // module state has changed
449     //
450     // Input:
451     //      - callback      : The callback object to be used by the module when
452     //                        the receiver decode state changes.
453     //                        De-register with a NULL pointer.
454     //
455     // Return value      : VCM_OK, on success.
456     //                     < 0,         on error.
457     virtual int32_t RegisterReceiveStateCallback(
458                                   VCMReceiveStateCallback* callback) = 0;
459 
460     // Waits for the next frame in the jitter buffer to become complete
461     // (waits no longer than maxWaitTimeMs), then passes it to the decoder for decoding.
462     // Should be called as often as possible to get the most out of the decoder.
463     //
464     // Return value      : VCM_OK, on success.
465     //                     < 0,         on error.
466     virtual int32_t Decode(uint16_t maxWaitTimeMs = 200) = 0;
467 
468     // Registers a callback which conveys the size of the render buffer.
469     virtual int RegisterRenderBufferSizeCallback(
470         VCMRenderBufferSizeCallback* callback) = 0;
471 
472     // Reset the decoder state to the initial state.
473     //
474     // Return value      : VCM_OK, on success.
475     //                     < 0,         on error.
476     virtual int32_t ResetDecoder() = 0;
477 
478     // API to get the codec which is currently used for decoding by the module.
479     //
480     // Input:
481     //      - currentReceiveCodec      : Settings for the codec to be registered.
482     //
483     // Return value      : VCM_OK, on success.
484     //                     < 0,         on error.
485     virtual int32_t ReceiveCodec(VideoCodec* currentReceiveCodec) const = 0;
486 
487     // API to get the codec type currently used for decoding by the module.
488     //
489     // Return value      : codecy type,            on success.
490     //                     kVideoCodecUnknown, on error or if no receive codec is registered
491     virtual VideoCodecType ReceiveCodec() const = 0;
492 
493     // Insert a parsed packet into the receiver side of the module. Will be placed in the
494     // jitter buffer waiting for the frame to become complete. Returns as soon as the packet
495     // has been placed in the jitter buffer.
496     //
497     // Input:
498     //      - incomingPayload      : Payload of the packet.
499     //      - payloadLength        : Length of the payload.
500     //      - rtpInfo              : The parsed header.
501     //
502     // Return value      : VCM_OK, on success.
503     //                     < 0,         on error.
504     virtual int32_t IncomingPacket(const uint8_t* incomingPayload,
505                                    size_t payloadLength,
506                                    const WebRtcRTPHeader& rtpInfo) = 0;
507 
508     // Minimum playout delay (Used for lip-sync). This is the minimum delay required
509     // to sync with audio. Not included in  VideoCodingModule::Delay()
510     // Defaults to 0 ms.
511     //
512     // Input:
513     //      - minPlayoutDelayMs   : Additional delay in ms.
514     //
515     // Return value      : VCM_OK, on success.
516     //                     < 0,         on error.
517     virtual int32_t SetMinimumPlayoutDelay(uint32_t minPlayoutDelayMs) = 0;
518 
519     // Set the time required by the renderer to render a frame.
520     //
521     // Input:
522     //      - timeMS        : The time in ms required by the renderer to render a frame.
523     //
524     // Return value      : VCM_OK, on success.
525     //                     < 0,         on error.
526     virtual int32_t SetRenderDelay(uint32_t timeMS) = 0;
527 
528     // The total delay desired by the VCM. Can be less than the minimum
529     // delay set with SetMinimumPlayoutDelay.
530     //
531     // Return value      : Total delay in ms, on success.
532     //                     < 0,               on error.
533     virtual int32_t Delay() const = 0;
534 
535     // Returns the number of packets discarded by the jitter buffer due to being
536     // too late. This can include duplicated packets which arrived after the
537     // frame was sent to the decoder. Therefore packets which were prematurely
538     // NACKed will be counted.
539     virtual uint32_t DiscardedPackets() const = 0;
540 
541 
542     // Robustness APIs
543 
544     // Set the receiver robustness mode. The mode decides how the receiver
545     // responds to losses in the stream. The type of counter-measure (soft or
546     // hard NACK, dual decoder, RPS, etc.) is selected through the
547     // robustnessMode parameter. The errorMode parameter decides if it is
548     // allowed to display frames corrupted by losses. Note that not all
549     // combinations of the two parameters are feasible. An error will be
550     // returned for invalid combinations.
551     // Input:
552     //      - robustnessMode : selected robustness mode.
553     //      - errorMode      : selected error mode.
554     //
555     // Return value      : VCM_OK, on success;
556     //                     < 0, on error.
557     virtual int SetReceiverRobustnessMode(ReceiverRobustness robustnessMode,
558                                           VCMDecodeErrorMode errorMode) = 0;
559 
560     // Set the decode error mode. The mode decides which errors (if any) are
561     // allowed in decodable frames. Note that setting decode_error_mode to
562     // anything other than kWithErrors without enabling nack will cause
563     // long-term freezes (resulting from frequent key frame requests) if
564     // packet loss occurs.
565     virtual void SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode) = 0;
566 
567     // Sets the maximum number of sequence numbers that we are allowed to NACK
568     // and the oldest sequence number that we will consider to NACK. If a
569     // sequence number older than |max_packet_age_to_nack| is missing
570     // a key frame will be requested. A key frame will also be requested if the
571     // time of incomplete or non-continuous frames in the jitter buffer is above
572     // |max_incomplete_time_ms|.
573     virtual void SetNackSettings(size_t max_nack_list_size,
574                                  int max_packet_age_to_nack,
575                                  int max_incomplete_time_ms) = 0;
576 
577     // Setting a desired delay to the VCM receiver. Video rendering will be
578     // delayed by at least desired_delay_ms.
579     virtual int SetMinReceiverDelay(int desired_delay_ms) = 0;
580 
581     // Set current load state of the CPU
582     virtual void SetCPULoadState(CPULoadState state) = 0;
583 
584     // Enables recording of debugging information.
585     virtual int StartDebugRecording(const char* file_name_utf8) = 0;
586 
587     // Disables recording of debugging information.
588     virtual int StopDebugRecording() = 0;
589 
590     // Lets the sender suspend video when the rate drops below
591     // |threshold_bps|, and turns back on when the rate goes back up above
592     // |threshold_bps| + |window_bps|.
593     virtual void SuspendBelowMinBitrate() = 0;
594 
595     // Returns true if SuspendBelowMinBitrate is engaged and the video has been
596     // suspended due to bandwidth limitations; otherwise false.
597     virtual bool VideoSuspended() const = 0;
598 
599     virtual void RegisterPreDecodeImageCallback(
600         EncodedImageCallback* observer) = 0;
601     virtual void RegisterPostEncodeImageCallback(
602         EncodedImageCallback* post_encode_callback) = 0;
603     // Releases pending decode calls, permitting faster thread shutdown.
604     virtual void TriggerDecoderShutdown() = 0;
605 };
606 
607 }  // namespace webrtc
608 
609 #endif // WEBRTC_MODULES_INTERFACE_VIDEO_CODING_H_
610