Transcoder: Fixed codec leaks on cancel.

When transcoding was cancelled, the VideoTrackTranscoder
held strong references to itself through its internal
codec handler work queue.
This commit clears the work queue and blocks new messages
from being stored on cancel.

Test: Unit test and address sanitizer.
Fixes: 168522198
Change-Id: I9c3a4469378a91a492c6872bafc6d494dadf2853
diff --git a/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp b/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
index c7d775c..5579868 100644
--- a/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
+++ b/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
@@ -40,7 +40,11 @@
 template <typename T>
 void VideoTrackTranscoder::BlockingQueue<T>::push(T const& value, bool front) {
     {
-        std::unique_lock<std::mutex> lock(mMutex);
+        std::scoped_lock lock(mMutex);
+        if (mAborted) {
+            return;
+        }
+
         if (front) {
             mQueue.push_front(value);
         } else {
@@ -52,7 +56,7 @@
 
 template <typename T>
 T VideoTrackTranscoder::BlockingQueue<T>::pop() {
-    std::unique_lock<std::mutex> lock(mMutex);
+    std::unique_lock lock(mMutex);
     while (mQueue.empty()) {
         mCondition.wait(lock);
     }
@@ -61,6 +65,14 @@
     return value;
 }
 
+// Note: Do not call if another thread might waiting in pop.
+template <typename T>
+void VideoTrackTranscoder::BlockingQueue<T>::abort() {
+    std::scoped_lock lock(mMutex);
+    mAborted = true;
+    mQueue.clear();
+}
+
 // The CodecWrapper class is used to let AMediaCodec instances outlive the transcoder object itself
 // by giving the codec a weak pointer to the transcoder. Codecs wrapped in this object are kept
 // alive by the transcoder and the codec's outstanding buffers. Once the transcoder stops and all
@@ -484,12 +496,14 @@
         message();
     }
 
+    mCodecMessageQueue.abort();
+    AMediaCodec_stop(mDecoder);
+
     // Return error if transcoding was stopped before it finished.
     if (mStopRequested && !mEosFromEncoder && mStatus == AMEDIA_OK) {
         mStatus = AMEDIA_ERROR_UNKNOWN;  // TODO: Define custom error codes?
     }
 
-    AMediaCodec_stop(mDecoder);
     return mStatus;
 }