ref: d58ac746a0be98fcf429a156e1a077b0e621fa82
parent: 92729951435f4548f51138a596bfafde06d21de9
author: Hank Peng <[email protected]>
date: Wed Dec 2 18:46:43 EST 2015
Avoid a potential deadlock between the main thread and worker thread when encoding or decoding complete
--- a/module/gmp-openh264.cpp
+++ b/module/gmp-openh264.cpp
@@ -187,7 +187,8 @@
encoder_ (nullptr),
max_payload_size_ (0),
callback_ (nullptr),
- stats_ ("Encoder") {
+ stats_ ("Encoder"),
+ shutting_down(false) {
AddRef();
}
@@ -361,6 +362,8 @@
}
virtual void EncodingComplete() {
+ shutting_down = true;
+
// Release the reference to the external objects, because it is no longer safe to call them
host_ = nullptr;
callback_ = nullptr;
@@ -389,6 +392,12 @@
}
}
+ void TrySyncRunOnMainThread(GMPTask* aTask) {
+ if (!shutting_down && g_platform_api) {
+ g_platform_api->syncrunonmainthread (aTask);
+ }
+ }
+
void Error (GMPErr error) {
if (callback_) {
callback_->Error (error);
@@ -466,20 +475,20 @@
if (!has_frame) {
// This frame must be destroyed on the main thread.
- g_platform_api->syncrunonmainthread (WrapTask (
- this,
- &OpenH264VideoEncoder::DestroyInputFrame_m,
- inputImage));
+ TrySyncRunOnMainThread (WrapTask (
+ this,
+ &OpenH264VideoEncoder::DestroyInputFrame_m,
+ inputImage));
return;
}
// Synchronously send this back to the main thread for delivery.
- g_platform_api->syncrunonmainthread (WrapTask (
- this,
- &OpenH264VideoEncoder::Encode_m,
- inputImage,
- &encoded,
- encoded_type));
+ TrySyncRunOnMainThread (WrapTask (
+ this,
+ &OpenH264VideoEncoder::Encode_m,
+ inputImage,
+ &encoded,
+ encoded_type));
}
void Encode_m (GMPVideoi420Frame* frame, SFrameBSInfo* encoded,
@@ -574,6 +583,7 @@
uint32_t max_payload_size_;
GMPVideoEncoderCallback* callback_;
FrameStats stats_;
+ bool shutting_down;
};
uint16_t readU16BE(const uint8_t* in) {
@@ -593,7 +603,8 @@
worker_thread_ (nullptr),
callback_ (nullptr),
decoder_ (nullptr),
- stats_ ("Decoder") {
+ stats_ ("Decoder"),
+ shutting_down(false) {
AddRef();
}
@@ -739,6 +750,8 @@
}
virtual void DecodingComplete() {
+ shutting_down = true;
+
// Release the reference to the external objects, because it is no longer safe to call them
host_ = nullptr;
callback_ = nullptr;
@@ -766,6 +779,13 @@
decoder_ = nullptr;
}
}
+
+ void TrySyncRunOnMainThread(GMPTask* aTask) {
+ if (!shutting_down && g_platform_api) {
+ g_platform_api->syncrunonmainthread (aTask);
+ }
+ }
+
void Error (GMPErr error) {
if (callback_) {
callback_->Error (error);
@@ -795,14 +815,14 @@
valid = true;
}
- g_platform_api->syncrunonmainthread (WrapTask (
- this,
- &OpenH264VideoDecoder::Decode_m,
- inputFrame,
- &decoded,
- data,
- renderTimeMs,
- valid));
+ TrySyncRunOnMainThread (WrapTask (
+ this,
+ &OpenH264VideoDecoder::Decode_m,
+ inputFrame,
+ &decoded,
+ data,
+ renderTimeMs,
+ valid));
}
// Return the decoded data back to the parent.
@@ -883,6 +903,7 @@
GMPVideoDecoderCallback* callback_;
ISVCDecoder* decoder_;
FrameStats stats_;
+ bool shutting_down;
};
extern "C" {