Index: webrtc/modules/video_coding/video_coding_impl.h |
diff --git a/webrtc/modules/video_coding/video_coding_impl.h b/webrtc/modules/video_coding/video_coding_impl.h |
index 5e547df07ae472c3a09236e61afb701b3a4a6b96..d6e722db3e04ee9e13a6d84d56fd79d578fbbada 100644 |
--- a/webrtc/modules/video_coding/video_coding_impl.h |
+++ b/webrtc/modules/video_coding/video_coding_impl.h |
@@ -35,6 +35,7 @@ |
namespace webrtc { |
+class ProcessThread; |
class VideoBitrateAllocator; |
class VideoBitrateAllocationObserver; |
@@ -150,7 +151,7 @@ class VideoReceiver : public Module { |
VCMTiming* timing, |
NackSender* nack_sender = nullptr, |
KeyFrameRequestSender* keyframe_request_sender = nullptr); |
- ~VideoReceiver(); |
+ ~VideoReceiver() override; |
int32_t RegisterReceiveCodec(const VideoCodec* receiveCodec, |
int32_t numberOfCores, |
@@ -168,8 +169,10 @@ class VideoReceiver : public Module { |
int32_t Decode(const webrtc::VCMEncodedFrame* frame); |
- // Called on the decoder thread when thread is exiting. |
- void DecodingStopped(); |
+#if defined(WEBRTC_ANDROID) |
+ // See https://bugs.chromium.org/p/webrtc/issues/detail?id=7361 |
+ void PollDecodedFrames(); |
+#endif |
int32_t IncomingPacket(const uint8_t* incomingPayload, |
size_t payloadLength, |
@@ -195,39 +198,66 @@ class VideoReceiver : public Module { |
int64_t TimeUntilNextProcess() override; |
void Process() override; |
+ void ProcessThreadAttached(ProcessThread* process_thread) override; |
void TriggerDecoderShutdown(); |
+ void DecoderThreadStarting(); |
+ void DecoderThreadStopped(); |
protected: |
- int32_t Decode(const webrtc::VCMEncodedFrame& frame) |
- EXCLUSIVE_LOCKS_REQUIRED(receive_crit_); |
+ int32_t Decode(const webrtc::VCMEncodedFrame& frame); |
int32_t RequestKeyFrame(); |
private: |
+ // Used for DCHECKing thread correctness. |
+ // In build where DCHECKs are enabled, will return false before |
+ // DecoderThreadStarting is called, then true until DecoderThreadStopped |
+ // is called. |
+ // In builds where DCHECKs aren't enabled, it will return true. |
+ bool IsDecoderThreadRunning(); |
+ |
rtc::ThreadChecker construction_thread_; |
+ rtc::ThreadChecker decoder_thread_; |
+ rtc::ThreadChecker module_thread_; |
Clock* const clock_; |
rtc::CriticalSection process_crit_; |
- rtc::CriticalSection receive_crit_; |
VCMTiming* _timing; |
VCMReceiver _receiver; |
VCMDecodedFrameCallback _decodedFrameCallback; |
- VCMFrameTypeCallback* _frameTypeCallback GUARDED_BY(process_crit_); |
- VCMReceiveStatisticsCallback* _receiveStatsCallback GUARDED_BY(process_crit_); |
- VCMPacketRequestCallback* _packetRequestCallback GUARDED_BY(process_crit_); |
- VCMFrameBuffer _frameFromFile; |
+ // These callbacks are set on the construction thread before being attached |
+ // to the module thread or decoding started, so a lock is not required. |
+ VCMFrameTypeCallback* _frameTypeCallback; |
+ VCMReceiveStatisticsCallback* _receiveStatsCallback; |
+ VCMPacketRequestCallback* _packetRequestCallback; |
+ |
+ // Used on both the module and decoder thread. |
bool _scheduleKeyRequest GUARDED_BY(process_crit_); |
bool drop_frames_until_keyframe_ GUARDED_BY(process_crit_); |
- size_t max_nack_list_size_ GUARDED_BY(process_crit_); |
- |
- VCMCodecDataBase _codecDataBase GUARDED_BY(receive_crit_); |
- EncodedImageCallback* pre_decode_image_callback_; |
- VCMProcessTimer _receiveStatsTimer; |
- VCMProcessTimer _retransmissionTimer; |
- VCMProcessTimer _keyRequestTimer; |
- QpParser qp_parser_; |
- ThreadUnsafeOneTimeEvent first_frame_received_; |
+ // Modified on the construction thread while not attached to the process |
+ // thread. Once attached to the process thread, its value is only read |
+ // so a lock is not required. |
+ size_t max_nack_list_size_; |
+ |
+ // Callbacks are set before the decoder thread starts. |
+ // Once the decoder thread has been started, usage of |_codecDataBase| moves |
+ // over to the decoder thread. |
+ VCMCodecDataBase _codecDataBase; |
+ EncodedImageCallback* const pre_decode_image_callback_; |
+ |
+ VCMProcessTimer _receiveStatsTimer ACCESS_ON(module_thread_); |
+ VCMProcessTimer _retransmissionTimer ACCESS_ON(module_thread_); |
+ VCMProcessTimer _keyRequestTimer ACCESS_ON(module_thread_); |
+ QpParser qp_parser_ ACCESS_ON(decoder_thread_); |
+ ThreadUnsafeOneTimeEvent first_frame_received_ ACCESS_ON(decoder_thread_); |
+ // Modified on the construction thread. Can be read without a lock and assumed |
+ // to be non-null on the module and decoder threads. |
+ ProcessThread* process_thread_ = nullptr; |
+ bool is_attached_to_process_thread_ ACCESS_ON(construction_thread_) = false; |
+#if RTC_DCHECK_IS_ON |
+ bool decoder_thread_is_running_ = false; |
+#endif |
}; |
} // namespace vcm |