blob: 2e100209e8d9569a8e1908ddda6b071c8dbc0d8f [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
Rasmus Brandtc4d253c2022-05-25 12:03:35 +020011#include "modules/video_coding/video_receiver2.h"
12
Niels Mölleree3d9952019-09-09 12:51:55 +020013#include <stddef.h>
14
15#include <cstdint>
16#include <vector>
17
Niels Mölleree3d9952019-09-09 12:51:55 +020018#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"
Rasmus Brandtc4d253c2022-05-25 12:03:35 +020024#include "modules/video_coding/timing/timing.h"
Niels Mölleree3d9952019-09-09 12:51:55 +020025#include "rtc_base/checks.h"
26#include "rtc_base/trace_event.h"
27#include "system_wrappers/include/clock.h"
28
29namespace webrtc {
30
Jonas Orelande02f9ee2022-03-25 12:43:14 +010031VideoReceiver2::VideoReceiver2(Clock* clock,
32 VCMTiming* timing,
Jonas Orelande62c2f22022-03-29 11:04:48 +020033 const FieldTrialsView& field_trials)
Niels Mölleree3d9952019-09-09 12:51:55 +020034 : clock_(clock),
35 timing_(timing),
Jonas Orelande02f9ee2022-03-25 12:43:14 +010036 decodedFrameCallback_(timing_, clock_, field_trials),
Niels Mölleree3d9952019-09-09 12:51:55 +020037 codecDataBase_() {
Johannes Kron16359f62021-02-18 23:37:22 +010038 decoder_sequence_checker_.Detach();
Niels Mölleree3d9952019-09-09 12:51:55 +020039}
40
41VideoReceiver2::~VideoReceiver2() {
Johannes Kron16359f62021-02-18 23:37:22 +010042 RTC_DCHECK_RUN_ON(&construction_sequence_checker_);
Niels Mölleree3d9952019-09-09 12:51:55 +020043}
44
45// Register a receive callback. Will be called whenever there is a new frame
46// ready for rendering.
47int32_t VideoReceiver2::RegisterReceiveCallback(
48 VCMReceiveCallback* receiveCallback) {
Johannes Kron16359f62021-02-18 23:37:22 +010049 RTC_DCHECK_RUN_ON(&construction_sequence_checker_);
Niels Mölleree3d9952019-09-09 12:51:55 +020050 RTC_DCHECK(!IsDecoderThreadRunning());
51 // This value is set before the decoder thread starts and unset after
52 // the decoder thread has been stopped.
53 decodedFrameCallback_.SetUserReceiveCallback(receiveCallback);
54 return VCM_OK;
55}
56
Johannes Kron16359f62021-02-18 23:37:22 +010057// Register an externally defined decoder object. This may be called on either
58// the construction sequence or the decoder sequence to allow for lazy creation
Artem Titovdcd7fc72021-08-09 13:02:57 +020059// of video decoders. If called on the decoder sequence `externalDecoder` cannot
Johannes Kron16359f62021-02-18 23:37:22 +010060// be a nullptr. It's the responsibility of the caller to make sure that the
61// access from the two sequences are mutually exclusive.
Niels Mölleree3d9952019-09-09 12:51:55 +020062void VideoReceiver2::RegisterExternalDecoder(VideoDecoder* externalDecoder,
63 uint8_t payloadType) {
Johannes Kron16359f62021-02-18 23:37:22 +010064 if (IsDecoderThreadRunning()) {
65 RTC_DCHECK_RUN_ON(&decoder_sequence_checker_);
66 // Don't allow deregistering decoders on the decoder thread.
67 RTC_DCHECK(externalDecoder != nullptr);
68 } else {
69 RTC_DCHECK_RUN_ON(&construction_sequence_checker_);
70 }
71
Niels Mölleree3d9952019-09-09 12:51:55 +020072 if (externalDecoder == nullptr) {
Johannes Kron16359f62021-02-18 23:37:22 +010073 codecDataBase_.DeregisterExternalDecoder(payloadType);
Niels Mölleree3d9952019-09-09 12:51:55 +020074 return;
75 }
Danil Chapovalov7b78a312021-08-06 12:30:02 +020076 codecDataBase_.RegisterExternalDecoder(payloadType, externalDecoder);
Niels Mölleree3d9952019-09-09 12:51:55 +020077}
78
Johannes Kron16359f62021-02-18 23:37:22 +010079bool VideoReceiver2::IsExternalDecoderRegistered(uint8_t payloadType) const {
80 RTC_DCHECK_RUN_ON(&decoder_sequence_checker_);
81 return codecDataBase_.IsExternalDecoderRegistered(payloadType);
82}
83
Niels Mölleree3d9952019-09-09 12:51:55 +020084void VideoReceiver2::DecoderThreadStarting() {
Johannes Kron16359f62021-02-18 23:37:22 +010085 RTC_DCHECK_RUN_ON(&construction_sequence_checker_);
Niels Mölleree3d9952019-09-09 12:51:55 +020086 RTC_DCHECK(!IsDecoderThreadRunning());
87#if RTC_DCHECK_IS_ON
88 decoder_thread_is_running_ = true;
89#endif
90}
91
92void VideoReceiver2::DecoderThreadStopped() {
Johannes Kron16359f62021-02-18 23:37:22 +010093 RTC_DCHECK_RUN_ON(&construction_sequence_checker_);
Niels Mölleree3d9952019-09-09 12:51:55 +020094 RTC_DCHECK(IsDecoderThreadRunning());
95#if RTC_DCHECK_IS_ON
96 decoder_thread_is_running_ = false;
Johannes Kron16359f62021-02-18 23:37:22 +010097 decoder_sequence_checker_.Detach();
Niels Mölleree3d9952019-09-09 12:51:55 +020098#endif
99}
100
101// Must be called from inside the receive side critical section.
102int32_t VideoReceiver2::Decode(const VCMEncodedFrame* frame) {
Johannes Kron16359f62021-02-18 23:37:22 +0100103 RTC_DCHECK_RUN_ON(&decoder_sequence_checker_);
Niels Mölleree3d9952019-09-09 12:51:55 +0200104 TRACE_EVENT0("webrtc", "VideoReceiver2::Decode");
105 // Change decoder if payload type has changed
106 VCMGenericDecoder* decoder =
107 codecDataBase_.GetDecoder(*frame, &decodedFrameCallback_);
108 if (decoder == nullptr) {
109 return VCM_NO_CODEC_REGISTERED;
110 }
Johannes Kron05f84872020-01-16 14:09:33 +0100111 return decoder->Decode(*frame, clock_->CurrentTime());
Niels Mölleree3d9952019-09-09 12:51:55 +0200112}
113
114// Register possible receive codecs, can be called multiple times
Danil Chapovalovba0a3062021-08-13 18:15:55 +0200115void VideoReceiver2::RegisterReceiveCodec(
Danil Chapovalov355b8d22021-08-13 16:50:37 +0200116 uint8_t payload_type,
117 const VideoDecoder::Settings& settings) {
Johannes Kron16359f62021-02-18 23:37:22 +0100118 RTC_DCHECK_RUN_ON(&construction_sequence_checker_);
Niels Mölleree3d9952019-09-09 12:51:55 +0200119 RTC_DCHECK(!IsDecoderThreadRunning());
Danil Chapovalovba0a3062021-08-13 18:15:55 +0200120 codecDataBase_.RegisterReceiveCodec(payload_type, settings);
Niels Mölleree3d9952019-09-09 12:51:55 +0200121}
122
123bool VideoReceiver2::IsDecoderThreadRunning() {
124#if RTC_DCHECK_IS_ON
125 return decoder_thread_is_running_;
126#else
127 return true;
128#endif
129}
130
131} // namespace webrtc