1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker #ifndef MODULES_VIDEO_CODING_GENERIC_DECODER_H_ 12*d9f75844SAndroid Build Coastguard Worker #define MODULES_VIDEO_CODING_GENERIC_DECODER_H_ 13*d9f75844SAndroid Build Coastguard Worker 14*d9f75844SAndroid Build Coastguard Worker #include <cstdint> 15*d9f75844SAndroid Build Coastguard Worker #include <deque> 16*d9f75844SAndroid Build Coastguard Worker #include <string> 17*d9f75844SAndroid Build Coastguard Worker #include <utility> 18*d9f75844SAndroid Build Coastguard Worker 19*d9f75844SAndroid Build Coastguard Worker #include "api/field_trials_view.h" 20*d9f75844SAndroid Build Coastguard Worker #include "api/sequence_checker.h" 21*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/video_decoder.h" 22*d9f75844SAndroid Build Coastguard Worker #include "modules/video_coding/encoded_frame.h" 23*d9f75844SAndroid Build Coastguard Worker #include "modules/video_coding/timing/timing.h" 24*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/synchronization/mutex.h" 25*d9f75844SAndroid Build Coastguard Worker 26*d9f75844SAndroid Build Coastguard Worker namespace webrtc { 27*d9f75844SAndroid Build Coastguard Worker 28*d9f75844SAndroid Build Coastguard Worker class VCMReceiveCallback; 29*d9f75844SAndroid Build Coastguard Worker 30*d9f75844SAndroid Build Coastguard Worker struct FrameInfo { 31*d9f75844SAndroid Build Coastguard Worker FrameInfo() = default; 32*d9f75844SAndroid Build Coastguard Worker FrameInfo(const FrameInfo&) = delete; 33*d9f75844SAndroid Build Coastguard Worker FrameInfo& operator=(const FrameInfo&) = delete; 34*d9f75844SAndroid Build Coastguard Worker FrameInfo(FrameInfo&&) = default; 35*d9f75844SAndroid Build Coastguard Worker FrameInfo& operator=(FrameInfo&&) = default; 36*d9f75844SAndroid Build Coastguard Worker 37*d9f75844SAndroid Build Coastguard Worker uint32_t rtp_timestamp; 38*d9f75844SAndroid Build Coastguard Worker // This is likely not optional, but some inputs seem to sometimes be negative. 39*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/13756): See if this can be replaced with Timestamp 40*d9f75844SAndroid Build Coastguard Worker // once all inputs to this field use Timestamp instead of an integer. 41*d9f75844SAndroid Build Coastguard Worker absl::optional<Timestamp> render_time; 42*d9f75844SAndroid Build Coastguard Worker absl::optional<Timestamp> decode_start; 43*d9f75844SAndroid Build Coastguard Worker VideoRotation rotation; 44*d9f75844SAndroid Build Coastguard Worker VideoContentType content_type; 45*d9f75844SAndroid Build Coastguard Worker EncodedImage::Timing timing; 46*d9f75844SAndroid Build Coastguard Worker int64_t ntp_time_ms; 47*d9f75844SAndroid Build Coastguard Worker RtpPacketInfos packet_infos; 48*d9f75844SAndroid Build Coastguard Worker // ColorSpace is not stored here, as it might be modified by decoders. 49*d9f75844SAndroid Build Coastguard Worker }; 50*d9f75844SAndroid Build Coastguard Worker 51*d9f75844SAndroid Build Coastguard Worker class VCMDecodedFrameCallback : public DecodedImageCallback { 52*d9f75844SAndroid Build Coastguard Worker public: 53*d9f75844SAndroid Build Coastguard Worker VCMDecodedFrameCallback(VCMTiming* timing, 54*d9f75844SAndroid Build Coastguard Worker Clock* clock, 55*d9f75844SAndroid Build Coastguard Worker const FieldTrialsView& field_trials); 56*d9f75844SAndroid Build Coastguard Worker ~VCMDecodedFrameCallback() override; 57*d9f75844SAndroid Build Coastguard Worker void SetUserReceiveCallback(VCMReceiveCallback* receiveCallback); 58*d9f75844SAndroid Build Coastguard Worker VCMReceiveCallback* UserReceiveCallback(); 59*d9f75844SAndroid Build Coastguard Worker 60*d9f75844SAndroid Build Coastguard Worker int32_t Decoded(VideoFrame& decodedImage) override; 61*d9f75844SAndroid Build Coastguard Worker int32_t Decoded(VideoFrame& decodedImage, int64_t decode_time_ms) override; 62*d9f75844SAndroid Build Coastguard Worker void Decoded(VideoFrame& decodedImage, 63*d9f75844SAndroid Build Coastguard Worker absl::optional<int32_t> decode_time_ms, 64*d9f75844SAndroid Build Coastguard Worker absl::optional<uint8_t> qp) override; 65*d9f75844SAndroid Build Coastguard Worker 66*d9f75844SAndroid Build Coastguard Worker void OnDecoderInfoChanged(const VideoDecoder::DecoderInfo& decoder_info); 67*d9f75844SAndroid Build Coastguard Worker 68*d9f75844SAndroid Build Coastguard Worker void Map(FrameInfo frameInfo); 69*d9f75844SAndroid Build Coastguard Worker void ClearTimestampMap(); 70*d9f75844SAndroid Build Coastguard Worker 71*d9f75844SAndroid Build Coastguard Worker private: 72*d9f75844SAndroid Build Coastguard Worker std::pair<absl::optional<FrameInfo>, size_t> FindFrameInfo( 73*d9f75844SAndroid Build Coastguard Worker uint32_t rtp_timestamp) RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_); 74*d9f75844SAndroid Build Coastguard Worker 75*d9f75844SAndroid Build Coastguard Worker SequenceChecker construction_thread_; 76*d9f75844SAndroid Build Coastguard Worker Clock* const _clock; 77*d9f75844SAndroid Build Coastguard Worker // This callback must be set before the decoder thread starts running 78*d9f75844SAndroid Build Coastguard Worker // and must only be unset when external threads (e.g decoder thread) 79*d9f75844SAndroid Build Coastguard Worker // have been stopped. Due to that, the variable should regarded as const 80*d9f75844SAndroid Build Coastguard Worker // while there are more than one threads involved, it must be set 81*d9f75844SAndroid Build Coastguard Worker // from the same thread, and therfore a lock is not required to access it. 82*d9f75844SAndroid Build Coastguard Worker VCMReceiveCallback* _receiveCallback = nullptr; 83*d9f75844SAndroid Build Coastguard Worker VCMTiming* _timing; 84*d9f75844SAndroid Build Coastguard Worker Mutex lock_; 85*d9f75844SAndroid Build Coastguard Worker std::deque<FrameInfo> frame_infos_ RTC_GUARDED_BY(lock_); 86*d9f75844SAndroid Build Coastguard Worker int64_t ntp_offset_; 87*d9f75844SAndroid Build Coastguard Worker }; 88*d9f75844SAndroid Build Coastguard Worker 89*d9f75844SAndroid Build Coastguard Worker class VCMGenericDecoder { 90*d9f75844SAndroid Build Coastguard Worker public: 91*d9f75844SAndroid Build Coastguard Worker explicit VCMGenericDecoder(VideoDecoder* decoder); 92*d9f75844SAndroid Build Coastguard Worker ~VCMGenericDecoder(); 93*d9f75844SAndroid Build Coastguard Worker 94*d9f75844SAndroid Build Coastguard Worker /** 95*d9f75844SAndroid Build Coastguard Worker * Initialize the decoder with the information from the `settings` 96*d9f75844SAndroid Build Coastguard Worker */ 97*d9f75844SAndroid Build Coastguard Worker bool Configure(const VideoDecoder::Settings& settings); 98*d9f75844SAndroid Build Coastguard Worker 99*d9f75844SAndroid Build Coastguard Worker /** 100*d9f75844SAndroid Build Coastguard Worker * Decode to a raw I420 frame, 101*d9f75844SAndroid Build Coastguard Worker * 102*d9f75844SAndroid Build Coastguard Worker * inputVideoBuffer reference to encoded video frame 103*d9f75844SAndroid Build Coastguard Worker */ 104*d9f75844SAndroid Build Coastguard Worker int32_t Decode(const VCMEncodedFrame& inputFrame, Timestamp now); 105*d9f75844SAndroid Build Coastguard Worker 106*d9f75844SAndroid Build Coastguard Worker /** 107*d9f75844SAndroid Build Coastguard Worker * Set decode callback. Deregistering while decoding is illegal. 108*d9f75844SAndroid Build Coastguard Worker */ 109*d9f75844SAndroid Build Coastguard Worker int32_t RegisterDecodeCompleteCallback(VCMDecodedFrameCallback* callback); 110*d9f75844SAndroid Build Coastguard Worker IsSameDecoder(VideoDecoder * decoder)111*d9f75844SAndroid Build Coastguard Worker bool IsSameDecoder(VideoDecoder* decoder) const { 112*d9f75844SAndroid Build Coastguard Worker return decoder_ == decoder; 113*d9f75844SAndroid Build Coastguard Worker } 114*d9f75844SAndroid Build Coastguard Worker 115*d9f75844SAndroid Build Coastguard Worker private: 116*d9f75844SAndroid Build Coastguard Worker VCMDecodedFrameCallback* _callback = nullptr; 117*d9f75844SAndroid Build Coastguard Worker VideoDecoder* const decoder_; 118*d9f75844SAndroid Build Coastguard Worker VideoContentType _last_keyframe_content_type; 119*d9f75844SAndroid Build Coastguard Worker VideoDecoder::DecoderInfo decoder_info_; 120*d9f75844SAndroid Build Coastguard Worker }; 121*d9f75844SAndroid Build Coastguard Worker 122*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc 123*d9f75844SAndroid Build Coastguard Worker 124*d9f75844SAndroid Build Coastguard Worker #endif // MODULES_VIDEO_CODING_GENERIC_DECODER_H_ 125