blob: 5ffb4f276e231f10249384ceb8cb72552ddb9538 [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
Niels Mölleree3d9952019-09-09 12:51:55 +020067void 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
75void 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.
85int32_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 }
Johannes Kron05f84872020-01-16 14:09:33 +010094 return decoder->Decode(*frame, clock_->CurrentTime());
Niels Mölleree3d9952019-09-09 12:51:55 +020095}
96
97// Register possible receive codecs, can be called multiple times
98int32_t VideoReceiver2::RegisterReceiveCodec(const VideoCodec* receiveCodec,
Niels Möller18c83d32020-08-07 14:14:49 +020099 int32_t numberOfCores) {
Niels Mölleree3d9952019-09-09 12:51:55 +0200100 RTC_DCHECK_RUN_ON(&construction_thread_checker_);
101 RTC_DCHECK(!IsDecoderThreadRunning());
102 if (receiveCodec == nullptr) {
103 return VCM_PARAMETER_ERROR;
104 }
Niels Möller18c83d32020-08-07 14:14:49 +0200105 if (!codecDataBase_.RegisterReceiveCodec(receiveCodec, numberOfCores)) {
Niels Mölleree3d9952019-09-09 12:51:55 +0200106 return -1;
107 }
108 return 0;
109}
110
111bool VideoReceiver2::IsDecoderThreadRunning() {
112#if RTC_DCHECK_IS_ON
113 return decoder_thread_is_running_;
114#else
115 return true;
116#endif
117}
118
119} // namespace webrtc