blob: d1e57d17be40fb843a416de1c14cf9a275c9ea75 [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 }
94 return decoder->Decode(*frame, clock_->TimeInMilliseconds());
95}
96
97// Register possible receive codecs, can be called multiple times
98int32_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
113bool 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