blob: 0a9ec49b290408d3c457bc8b41a32a1f64331b2e [file] [log] [blame]
Niels Mölleree3d9952019-09-09 12:51:55 +02001/*
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
29namespace webrtc {
30
31VideoReceiver2::VideoReceiver2(Clock* clock, VCMTiming* timing)
32 : clock_(clock),
33 timing_(timing),
34 decodedFrameCallback_(timing_, clock_),
35 codecDataBase_() {
36 decoder_thread_checker_.Detach();
37}
38
39VideoReceiver2::~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.
45int32_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.
56void 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
67void VideoReceiver2::TriggerDecoderShutdown() {
68 RTC_DCHECK_RUN_ON(&construction_thread_checker_);
69 RTC_DCHECK(IsDecoderThreadRunning());
70}
71
72void VideoReceiver2::DecoderThreadStarting() {
73 RTC_DCHECK_RUN_ON(&construction_thread_checker_);
74 RTC_DCHECK(!IsDecoderThreadRunning());
75#if RTC_DCHECK_IS_ON
76 decoder_thread_is_running_ = true;
77#endif
78}
79
80void VideoReceiver2::DecoderThreadStopped() {
81 RTC_DCHECK_RUN_ON(&construction_thread_checker_);
82 RTC_DCHECK(IsDecoderThreadRunning());
83#if RTC_DCHECK_IS_ON
84 decoder_thread_is_running_ = false;
85 decoder_thread_checker_.Detach();
86#endif
87}
88
89// Must be called from inside the receive side critical section.
90int32_t VideoReceiver2::Decode(const VCMEncodedFrame* frame) {
91 RTC_DCHECK_RUN_ON(&decoder_thread_checker_);
92 TRACE_EVENT0("webrtc", "VideoReceiver2::Decode");
93 // Change decoder if payload type has changed
94 VCMGenericDecoder* decoder =
95 codecDataBase_.GetDecoder(*frame, &decodedFrameCallback_);
96 if (decoder == nullptr) {
97 return VCM_NO_CODEC_REGISTERED;
98 }
99 return decoder->Decode(*frame, clock_->TimeInMilliseconds());
100}
101
102// Register possible receive codecs, can be called multiple times
103int32_t VideoReceiver2::RegisterReceiveCodec(const VideoCodec* receiveCodec,
104 int32_t numberOfCores,
105 bool requireKeyFrame) {
106 RTC_DCHECK_RUN_ON(&construction_thread_checker_);
107 RTC_DCHECK(!IsDecoderThreadRunning());
108 if (receiveCodec == nullptr) {
109 return VCM_PARAMETER_ERROR;
110 }
111 if (!codecDataBase_.RegisterReceiveCodec(receiveCodec, numberOfCores,
112 requireKeyFrame)) {
113 return -1;
114 }
115 return 0;
116}
117
118bool VideoReceiver2::IsDecoderThreadRunning() {
119#if RTC_DCHECK_IS_ON
120 return decoder_thread_is_running_;
121#else
122 return true;
123#endif
124}
125
126} // namespace webrtc