blob: add6917d10c2fffdf2cdfadeeeb1749ef9e905cd [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_() {
Johannes Kron16359f62021-02-18 23:37:22 +010036 decoder_sequence_checker_.Detach();
Niels Mölleree3d9952019-09-09 12:51:55 +020037}
38
39VideoReceiver2::~VideoReceiver2() {
Johannes Kron16359f62021-02-18 23:37:22 +010040 RTC_DCHECK_RUN_ON(&construction_sequence_checker_);
Niels Mölleree3d9952019-09-09 12:51:55 +020041}
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) {
Johannes Kron16359f62021-02-18 23:37:22 +010047 RTC_DCHECK_RUN_ON(&construction_sequence_checker_);
Niels Mölleree3d9952019-09-09 12:51:55 +020048 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
Johannes Kron16359f62021-02-18 23:37:22 +010055// Register an externally defined decoder object. This may be called on either
56// the construction sequence or the decoder sequence to allow for lazy creation
Artem Titovdcd7fc72021-08-09 13:02:57 +020057// of video decoders. If called on the decoder sequence `externalDecoder` cannot
Johannes Kron16359f62021-02-18 23:37:22 +010058// be a nullptr. It's the responsibility of the caller to make sure that the
59// access from the two sequences are mutually exclusive.
Niels Mölleree3d9952019-09-09 12:51:55 +020060void VideoReceiver2::RegisterExternalDecoder(VideoDecoder* externalDecoder,
61 uint8_t payloadType) {
Johannes Kron16359f62021-02-18 23:37:22 +010062 if (IsDecoderThreadRunning()) {
63 RTC_DCHECK_RUN_ON(&decoder_sequence_checker_);
64 // Don't allow deregistering decoders on the decoder thread.
65 RTC_DCHECK(externalDecoder != nullptr);
66 } else {
67 RTC_DCHECK_RUN_ON(&construction_sequence_checker_);
68 }
69
Niels Mölleree3d9952019-09-09 12:51:55 +020070 if (externalDecoder == nullptr) {
Johannes Kron16359f62021-02-18 23:37:22 +010071 codecDataBase_.DeregisterExternalDecoder(payloadType);
Niels Mölleree3d9952019-09-09 12:51:55 +020072 return;
73 }
Danil Chapovalov7b78a312021-08-06 12:30:02 +020074 codecDataBase_.RegisterExternalDecoder(payloadType, externalDecoder);
Niels Mölleree3d9952019-09-09 12:51:55 +020075}
76
Johannes Kron16359f62021-02-18 23:37:22 +010077bool VideoReceiver2::IsExternalDecoderRegistered(uint8_t payloadType) const {
78 RTC_DCHECK_RUN_ON(&decoder_sequence_checker_);
79 return codecDataBase_.IsExternalDecoderRegistered(payloadType);
80}
81
Niels Mölleree3d9952019-09-09 12:51:55 +020082void VideoReceiver2::DecoderThreadStarting() {
Johannes Kron16359f62021-02-18 23:37:22 +010083 RTC_DCHECK_RUN_ON(&construction_sequence_checker_);
Niels Mölleree3d9952019-09-09 12:51:55 +020084 RTC_DCHECK(!IsDecoderThreadRunning());
85#if RTC_DCHECK_IS_ON
86 decoder_thread_is_running_ = true;
87#endif
88}
89
90void VideoReceiver2::DecoderThreadStopped() {
Johannes Kron16359f62021-02-18 23:37:22 +010091 RTC_DCHECK_RUN_ON(&construction_sequence_checker_);
Niels Mölleree3d9952019-09-09 12:51:55 +020092 RTC_DCHECK(IsDecoderThreadRunning());
93#if RTC_DCHECK_IS_ON
94 decoder_thread_is_running_ = false;
Johannes Kron16359f62021-02-18 23:37:22 +010095 decoder_sequence_checker_.Detach();
Niels Mölleree3d9952019-09-09 12:51:55 +020096#endif
97}
98
99// Must be called from inside the receive side critical section.
100int32_t VideoReceiver2::Decode(const VCMEncodedFrame* frame) {
Johannes Kron16359f62021-02-18 23:37:22 +0100101 RTC_DCHECK_RUN_ON(&decoder_sequence_checker_);
Niels Mölleree3d9952019-09-09 12:51:55 +0200102 TRACE_EVENT0("webrtc", "VideoReceiver2::Decode");
103 // Change decoder if payload type has changed
104 VCMGenericDecoder* decoder =
105 codecDataBase_.GetDecoder(*frame, &decodedFrameCallback_);
106 if (decoder == nullptr) {
107 return VCM_NO_CODEC_REGISTERED;
108 }
Johannes Kron05f84872020-01-16 14:09:33 +0100109 return decoder->Decode(*frame, clock_->CurrentTime());
Niels Mölleree3d9952019-09-09 12:51:55 +0200110}
111
112// Register possible receive codecs, can be called multiple times
Danil Chapovalov355b8d22021-08-13 16:50:37 +0200113bool VideoReceiver2::RegisterReceiveCodec(
114 uint8_t payload_type,
115 const VideoDecoder::Settings& settings) {
Johannes Kron16359f62021-02-18 23:37:22 +0100116 RTC_DCHECK_RUN_ON(&construction_sequence_checker_);
Niels Mölleree3d9952019-09-09 12:51:55 +0200117 RTC_DCHECK(!IsDecoderThreadRunning());
Danil Chapovalov355b8d22021-08-13 16:50:37 +0200118 return codecDataBase_.RegisterReceiveCodec(payload_type, settings);
Niels Mölleree3d9952019-09-09 12:51:55 +0200119}
120
121bool VideoReceiver2::IsDecoderThreadRunning() {
122#if RTC_DCHECK_IS_ON
123 return decoder_thread_is_running_;
124#else
125 return true;
126#endif
127}
128
129} // namespace webrtc