Merge "Fix producer usage in virtual camera" into main
diff --git a/media/codec2/hal/client/ApexCodecsLazy.cpp b/media/codec2/hal/client/ApexCodecsLazy.cpp
index 2db4cb1..cd7953e 100644
--- a/media/codec2/hal/client/ApexCodecsLazy.cpp
+++ b/media/codec2/hal/client/ApexCodecsLazy.cpp
@@ -64,6 +64,11 @@
 public:
     ApexCodecsLazyLoader() = default;
 
+    static ApexCodecsLazyLoader &Get() {
+        static ::android::base::NoDestructor<ApexCodecsLazyLoader> sLoader;
+        return *sLoader;
+    }
+
     void *getMethodAt(enum MethodIndex index) {
         RWLock::AutoRLock l(mLock);
         if (mInit) {
@@ -79,11 +84,6 @@
     }
 
 private:
-    RWLock mLock;
-    // Table of methods pointers in libapexcodecs APIs.
-    void* mMethods[k_MethodCount];
-    bool mInit{false};
-
     static void* LoadLibapexcodecs(int dlopen_flags) {
         return dlopen("libapexcodecs.so", dlopen_flags);
     }
@@ -144,20 +144,20 @@
         mInit = true;
         return true;
     }
-};
 
-static ApexCodecsLazyLoader &GetLoader() {
-    ::android::base::NoDestructor<ApexCodecsLazyLoader> sLoader;
-    return *sLoader;
-}
+    RWLock mLock;
+    // Table of methods pointers in libapexcodecs APIs.
+    void* mMethods[k_MethodCount];
+    bool mInit{false};
+};
 
 }  // anonymous namespace
 
-#define INVOKE_METHOD(name, returnIfNull, args...)              \
-    do {                                                        \
-        void* method = GetLoader().getMethodAt(k_##name);       \
-        if (!method) return (returnIfNull);                     \
-        return reinterpret_cast<decltype(&name)>(method)(args); \
+#define INVOKE_METHOD(name, returnIfNull, args...)                          \
+    do {                                                                    \
+        void* method = ApexCodecsLazyLoader::Get().getMethodAt(k_##name);   \
+        if (!method) return (returnIfNull);                                 \
+        return reinterpret_cast<decltype(&name)>(method)(args);             \
     } while (0)
 
 //
diff --git a/media/libaudioclient/AudioTrackShared.cpp b/media/libaudioclient/AudioTrackShared.cpp
index e3b79b2..359f3c1 100644
--- a/media/libaudioclient/AudioTrackShared.cpp
+++ b/media/libaudioclient/AudioTrackShared.cpp
@@ -310,8 +310,16 @@
             ts = NULL;
             break;
         }
+
         int32_t old = android_atomic_and(~CBLK_FUTEX_WAKE, &cblk->mFutex);
-        if (!(old & CBLK_FUTEX_WAKE)) {
+
+        // Check inactive to prevent waiting if the track has been disabled due to underrun
+        // (or invalidated).  The subsequent call to obtainBufer will return NOT_ENOUGH_DATA
+        // (or DEAD_OBJECT) and restart (or restore) the track.
+        const int32_t current_flags = android_atomic_acquire_load(&cblk->mFlags);
+        const bool inactive = current_flags & (CBLK_INVALID | CBLK_DISABLED);
+
+        if (!(old & CBLK_FUTEX_WAKE) && !inactive) {
             if (measure && !beforeIsValid) {
                 clock_gettime(CLOCK_MONOTONIC, &before);
                 beforeIsValid = true;