1 /*
2 * Copyright (c) 2013 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 #include "modules/video_coding/video_receiver2.h"
12
13 #include <stddef.h>
14
15 #include <cstdint>
16 #include <utility>
17 #include <vector>
18
19 #include "absl/algorithm/container.h"
20 #include "api/video_codecs/video_codec.h"
21 #include "api/video_codecs/video_decoder.h"
22 #include "modules/video_coding/decoder_database.h"
23 #include "modules/video_coding/encoded_frame.h"
24 #include "modules/video_coding/generic_decoder.h"
25 #include "modules/video_coding/include/video_coding_defines.h"
26 #include "modules/video_coding/timing/timing.h"
27 #include "rtc_base/checks.h"
28 #include "rtc_base/trace_event.h"
29 #include "system_wrappers/include/clock.h"
30
31 namespace webrtc {
32
VideoReceiver2(Clock * clock,VCMTiming * timing,const FieldTrialsView & field_trials)33 VideoReceiver2::VideoReceiver2(Clock* clock,
34 VCMTiming* timing,
35 const FieldTrialsView& field_trials)
36 : clock_(clock),
37 decoded_frame_callback_(timing, clock_, field_trials),
38 codec_database_() {
39 decoder_sequence_checker_.Detach();
40 }
41
~VideoReceiver2()42 VideoReceiver2::~VideoReceiver2() {
43 RTC_DCHECK_RUN_ON(&construction_sequence_checker_);
44 }
45
46 // Register a receive callback. Will be called whenever there is a new frame
47 // ready for rendering.
RegisterReceiveCallback(VCMReceiveCallback * receive_callback)48 int32_t VideoReceiver2::RegisterReceiveCallback(
49 VCMReceiveCallback* receive_callback) {
50 RTC_DCHECK_RUN_ON(&construction_sequence_checker_);
51 // This value is set before the decoder thread starts and unset after
52 // the decoder thread has been stopped.
53 decoded_frame_callback_.SetUserReceiveCallback(receive_callback);
54 return VCM_OK;
55 }
56
RegisterExternalDecoder(std::unique_ptr<VideoDecoder> decoder,uint8_t payload_type)57 void VideoReceiver2::RegisterExternalDecoder(
58 std::unique_ptr<VideoDecoder> decoder,
59 uint8_t payload_type) {
60 RTC_DCHECK_RUN_ON(&decoder_sequence_checker_);
61 RTC_DCHECK(decoded_frame_callback_.UserReceiveCallback());
62
63 if (decoder) {
64 RTC_DCHECK(!codec_database_.IsExternalDecoderRegistered(payload_type));
65 codec_database_.RegisterExternalDecoder(payload_type, std::move(decoder));
66 } else {
67 codec_database_.DeregisterExternalDecoder(payload_type);
68 }
69 }
70
IsExternalDecoderRegistered(uint8_t payload_type) const71 bool VideoReceiver2::IsExternalDecoderRegistered(uint8_t payload_type) const {
72 RTC_DCHECK_RUN_ON(&decoder_sequence_checker_);
73 return codec_database_.IsExternalDecoderRegistered(payload_type);
74 }
75
76 // Must be called from inside the receive side critical section.
Decode(const VCMEncodedFrame * frame)77 int32_t VideoReceiver2::Decode(const VCMEncodedFrame* frame) {
78 RTC_DCHECK_RUN_ON(&decoder_sequence_checker_);
79 TRACE_EVENT0("webrtc", "VideoReceiver2::Decode");
80 // Change decoder if payload type has changed.
81 VCMGenericDecoder* decoder =
82 codec_database_.GetDecoder(*frame, &decoded_frame_callback_);
83 if (decoder == nullptr) {
84 return VCM_NO_CODEC_REGISTERED;
85 }
86 return decoder->Decode(*frame, clock_->CurrentTime());
87 }
88
89 // Register possible receive codecs, can be called multiple times.
90 // Called before decoder thread is started.
RegisterReceiveCodec(uint8_t payload_type,const VideoDecoder::Settings & settings)91 void VideoReceiver2::RegisterReceiveCodec(
92 uint8_t payload_type,
93 const VideoDecoder::Settings& settings) {
94 RTC_DCHECK_RUN_ON(&construction_sequence_checker_);
95 codec_database_.RegisterReceiveCodec(payload_type, settings);
96 }
97
DeregisterReceiveCodec(uint8_t payload_type)98 void VideoReceiver2::DeregisterReceiveCodec(uint8_t payload_type) {
99 RTC_DCHECK_RUN_ON(&construction_sequence_checker_);
100 codec_database_.DeregisterReceiveCodec(payload_type);
101 }
102
DeregisterReceiveCodecs()103 void VideoReceiver2::DeregisterReceiveCodecs() {
104 RTC_DCHECK_RUN_ON(&construction_sequence_checker_);
105 codec_database_.DeregisterReceiveCodecs();
106 }
107
108 } // namespace webrtc
109