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 <stddef.h>
12
13 #include <cstdint>
14 #include <vector>
15
16 #include "modules/video_coding/video_receiver2.h"
17
18 #include "api/video_codecs/video_codec.h"
19 #include "api/video_codecs/video_decoder.h"
20 #include "modules/video_coding/decoder_database.h"
21 #include "modules/video_coding/encoded_frame.h"
22 #include "modules/video_coding/generic_decoder.h"
23 #include "modules/video_coding/include/video_coding_defines.h"
24 #include "modules/video_coding/timing.h"
25 #include "rtc_base/checks.h"
26 #include "rtc_base/trace_event.h"
27 #include "system_wrappers/include/clock.h"
28
29 namespace webrtc {
30
VideoReceiver2(Clock * clock,VCMTiming * timing)31 VideoReceiver2::VideoReceiver2(Clock* clock, VCMTiming* timing)
32 : clock_(clock),
33 timing_(timing),
34 decodedFrameCallback_(timing_, clock_),
35 codecDataBase_() {
36 decoder_thread_checker_.Detach();
37 }
38
~VideoReceiver2()39 VideoReceiver2::~VideoReceiver2() {
40 RTC_DCHECK_RUN_ON(&construction_thread_checker_);
41 }
42
43 // Register a receive callback. Will be called whenever there is a new frame
44 // ready for rendering.
RegisterReceiveCallback(VCMReceiveCallback * receiveCallback)45 int32_t VideoReceiver2::RegisterReceiveCallback(
46 VCMReceiveCallback* receiveCallback) {
47 RTC_DCHECK_RUN_ON(&construction_thread_checker_);
48 RTC_DCHECK(!IsDecoderThreadRunning());
49 // This value is set before the decoder thread starts and unset after
50 // the decoder thread has been stopped.
51 decodedFrameCallback_.SetUserReceiveCallback(receiveCallback);
52 return VCM_OK;
53 }
54
55 // Register an externally defined decoder object.
RegisterExternalDecoder(VideoDecoder * externalDecoder,uint8_t payloadType)56 void VideoReceiver2::RegisterExternalDecoder(VideoDecoder* externalDecoder,
57 uint8_t payloadType) {
58 RTC_DCHECK_RUN_ON(&construction_thread_checker_);
59 RTC_DCHECK(!IsDecoderThreadRunning());
60 if (externalDecoder == nullptr) {
61 RTC_CHECK(codecDataBase_.DeregisterExternalDecoder(payloadType));
62 return;
63 }
64 codecDataBase_.RegisterExternalDecoder(externalDecoder, payloadType);
65 }
66
DecoderThreadStarting()67 void VideoReceiver2::DecoderThreadStarting() {
68 RTC_DCHECK_RUN_ON(&construction_thread_checker_);
69 RTC_DCHECK(!IsDecoderThreadRunning());
70 #if RTC_DCHECK_IS_ON
71 decoder_thread_is_running_ = true;
72 #endif
73 }
74
DecoderThreadStopped()75 void VideoReceiver2::DecoderThreadStopped() {
76 RTC_DCHECK_RUN_ON(&construction_thread_checker_);
77 RTC_DCHECK(IsDecoderThreadRunning());
78 #if RTC_DCHECK_IS_ON
79 decoder_thread_is_running_ = false;
80 decoder_thread_checker_.Detach();
81 #endif
82 }
83
84 // Must be called from inside the receive side critical section.
Decode(const VCMEncodedFrame * frame)85 int32_t VideoReceiver2::Decode(const VCMEncodedFrame* frame) {
86 RTC_DCHECK_RUN_ON(&decoder_thread_checker_);
87 TRACE_EVENT0("webrtc", "VideoReceiver2::Decode");
88 // Change decoder if payload type has changed
89 VCMGenericDecoder* decoder =
90 codecDataBase_.GetDecoder(*frame, &decodedFrameCallback_);
91 if (decoder == nullptr) {
92 return VCM_NO_CODEC_REGISTERED;
93 }
94 return decoder->Decode(*frame, clock_->CurrentTime());
95 }
96
97 // Register possible receive codecs, can be called multiple times
RegisterReceiveCodec(const VideoCodec * receiveCodec,int32_t numberOfCores,bool requireKeyFrame)98 int32_t VideoReceiver2::RegisterReceiveCodec(const VideoCodec* receiveCodec,
99 int32_t numberOfCores,
100 bool requireKeyFrame) {
101 RTC_DCHECK_RUN_ON(&construction_thread_checker_);
102 RTC_DCHECK(!IsDecoderThreadRunning());
103 if (receiveCodec == nullptr) {
104 return VCM_PARAMETER_ERROR;
105 }
106 if (!codecDataBase_.RegisterReceiveCodec(receiveCodec, numberOfCores,
107 requireKeyFrame)) {
108 return -1;
109 }
110 return 0;
111 }
112
IsDecoderThreadRunning()113 bool VideoReceiver2::IsDecoderThreadRunning() {
114 #if RTC_DCHECK_IS_ON
115 return decoder_thread_is_running_;
116 #else
117 return true;
118 #endif
119 }
120
121 } // namespace webrtc
122