Merge "Camera: Clarify manual capture behavior for logical camera" into qt-dev
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.cpp b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
index 6509a88..6dab70b 100644
--- a/media/codec2/components/vpx/C2SoftVpxEnc.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
@@ -127,14 +127,14 @@
     }
 
     switch (mBitrateMode->value) {
-        case C2Config::BITRATE_VARIABLE:
-            mBitrateControlMode = VPX_VBR;
-            break;
         case C2Config::BITRATE_CONST:
-        default:
             mBitrateControlMode = VPX_CBR;
             break;
-        break;
+        case C2Config::BITRATE_VARIABLE:
+        [[fallthrough]];
+        default:
+            mBitrateControlMode = VPX_VBR;
+            break;
     }
 
     setCodecSpecificInterface();
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.h b/media/codec2/components/vpx/C2SoftVpxEnc.h
index 90758f9..62ccd1b 100644
--- a/media/codec2/components/vpx/C2SoftVpxEnc.h
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.h
@@ -275,7 +275,7 @@
         addParameter(
             DefineParam(mBitrateMode, C2_PARAMKEY_BITRATE_MODE)
                 .withDefault(new C2StreamBitrateModeTuning::output(
-                        0u, C2Config::BITRATE_CONST))
+                        0u, C2Config::BITRATE_VARIABLE))
                 .withFields({
                     C2F(mBitrateMode, value).oneOf({
                         C2Config::BITRATE_CONST, C2Config::BITRATE_VARIABLE })
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/Android.bp b/media/codec2/hidl/1.0/vts/functional/audio/Android.bp
index 687754b..65f0d09 100644
--- a/media/codec2/hidl/1.0/vts/functional/audio/Android.bp
+++ b/media/codec2/hidl/1.0/vts/functional/audio/Android.bp
@@ -15,19 +15,19 @@
  */
 
 cc_test {
-    name: "VtsHidlC2V1_0TargetAudioDecTest",
-    defaults: ["VtsMediaC2V1_0Defaults"],
+    name: "VtsHalMediaC2V1_0TargetAudioDecTest",
+    defaults: ["VtsHalMediaC2V1_0Defaults"],
     srcs: [
-        "VtsHidlC2V1_0TargetAudioDecTest.cpp",
+        "VtsHalMediaC2V1_0TargetAudioDecTest.cpp",
         //"media_audio_hidl_test_common.cpp"
     ],
 }
 
 cc_test {
-    name: "VtsHidlC2V1_0TargetAudioEncTest",
-    defaults: ["VtsMediaC2V1_0Defaults"],
+    name: "VtsHalMediaC2V1_0TargetAudioEncTest",
+    defaults: ["VtsHalMediaC2V1_0Defaults"],
     srcs: [
-        "VtsHidlC2V1_0TargetAudioEncTest.cpp",
+        "VtsHalMediaC2V1_0TargetAudioEncTest.cpp",
         //"media_audio_hidl_test_common.cpp"
     ],
 }
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/VtsHidlC2V1_0TargetAudioDecTest.cpp b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp
similarity index 100%
rename from media/codec2/hidl/1.0/vts/functional/audio/VtsHidlC2V1_0TargetAudioDecTest.cpp
rename to media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/VtsHidlC2V1_0TargetAudioEncTest.cpp b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp
similarity index 100%
rename from media/codec2/hidl/1.0/vts/functional/audio/VtsHidlC2V1_0TargetAudioEncTest.cpp
rename to media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp
diff --git a/media/codec2/hidl/1.0/vts/functional/common/Android.bp b/media/codec2/hidl/1.0/vts/functional/common/Android.bp
index da0061a..a011ba3 100644
--- a/media/codec2/hidl/1.0/vts/functional/common/Android.bp
+++ b/media/codec2/hidl/1.0/vts/functional/common/Android.bp
@@ -1,5 +1,5 @@
 cc_library_static {
-    name: "VtsMediaC2V1_0CommonUtil",
+    name: "VtsHalMediaC2V1_0CommonUtil",
     defaults: [
         "VtsHalTargetTestDefaults",
         "libcodec2-hidl-client-defaults",
@@ -17,14 +17,14 @@
 }
 
 cc_defaults {
-    name: "VtsMediaC2V1_0Defaults",
+    name: "VtsHalMediaC2V1_0Defaults",
     defaults: [
         "VtsHalTargetTestDefaults",
         "libcodec2-hidl-client-defaults",
     ],
 
     static_libs: [
-        "VtsMediaC2V1_0CommonUtil",
+        "VtsHalMediaC2V1_0CommonUtil",
     ],
 
     shared_libs: [
diff --git a/media/codec2/hidl/1.0/vts/functional/common/README.md b/media/codec2/hidl/1.0/vts/functional/common/README.md
index 3deab10..50e8356 100644
--- a/media/codec2/hidl/1.0/vts/functional/common/README.md
+++ b/media/codec2/hidl/1.0/vts/functional/common/README.md
@@ -3,29 +3,29 @@
 #### master :
 Functionality of master is to enumerate all the Codec2 components available in C2 media service.
 
-usage: VtsHidlC2V1\_0TargetMasterTest -I default
+usage: VtsHalMediaC2V1\_0TargetMasterTest -I default
 
 #### component :
 Functionality of component test is to validate common functionality across all the Codec2 components available in C2 media service. For a standard C2 component, these tests are expected to pass.
 
-usage: VtsHidlC2V1\_0TargetComponentTest -I software -C <comp name>
-example: VtsHidlC2V1\_0TargetComponentTest -I software -C c2.android.vorbis.decoder
+usage: VtsHalMediaC2V1\_0TargetComponentTest -I software -C <comp name>
+example: VtsHalMediaC2V1\_0TargetComponentTest -I software -C c2.android.vorbis.decoder
 
 #### audio :
 Functionality of audio test is to validate audio specific functionality Codec2 components. The resource files for this test are taken from media/codec2/hidl/1.0/vts/functional/res. The path to these files on the device is required to be given for bitstream tests.
 
-usage: VtsHidlC2V1\_0TargetAudioDecTest -I default -C <comp name> -P /sdcard/res/
-usage: VtsHidlC2V1\_0TargetAudioEncTest -I software -C <comp name> -P /sdcard/res/
+usage: VtsHalMediaC2V1\_0TargetAudioDecTest -I default -C <comp name> -P /sdcard/media/
+usage: VtsHalMediaC2V1\_0TargetAudioEncTest -I software -C <comp name> -P /sdcard/media/
 
-example: VtsHidlC2V1\_0TargetAudioDecTest -I software -C c2.android.flac.decoder -P /sdcard/res/
-example: VtsHidlC2V1\_0TargetAudioEncTest -I software -C c2.android.opus.encoder -P /sdcard/res/
+example: VtsHalMediaC2V1\_0TargetAudioDecTest -I software -C c2.android.flac.decoder -P /sdcard/media/
+example: VtsHalMediaC2V1\_0TargetAudioEncTest -I software -C c2.android.opus.encoder -P /sdcard/media/
 
 #### video :
 Functionality of video test is to validate video specific functionality Codec2 components. The resource files for this test are taken from media/codec2/hidl/1.0/vts/functional/res. The path to these files on the device is required to be given for bitstream tests.
 
-usage: VtsHidlC2V1\_0TargetVideoDecTest -I default -C <comp name> -P /sdcard/res/
-usage: VtsHidlC2V1\_0TargetVideoEncTest -I software -C <comp name> -P /sdcard/res/
+usage: VtsHalMediaC2V1\_0TargetVideoDecTest -I default -C <comp name> -P /sdcard/media/
+usage: VtsHalMediaC2V1\_0TargetVideoEncTest -I software -C <comp name> -P /sdcard/media/
 
-example: VtsHidlC2V1\_0TargetVideoDecTest -I software -C c2.android.avc.decoder -P /sdcard/res/
-example: VtsHidlC2V1\_0TargetVideoEncTest -I software -C c2.android.vp9.encoder -P /sdcard/res/
+example: VtsHalMediaC2V1\_0TargetVideoDecTest -I software -C c2.android.avc.decoder -P /sdcard/media/
+example: VtsHalMediaC2V1\_0TargetVideoEncTest -I software -C c2.android.vp9.encoder -P /sdcard/media/
 
diff --git a/media/codec2/hidl/1.0/vts/functional/component/Android.bp b/media/codec2/hidl/1.0/vts/functional/component/Android.bp
index 4b913b6..7ec64ee 100644
--- a/media/codec2/hidl/1.0/vts/functional/component/Android.bp
+++ b/media/codec2/hidl/1.0/vts/functional/component/Android.bp
@@ -15,8 +15,8 @@
  */
 
 cc_test {
-    name: "VtsHidlC2V1_0TargetComponentTest",
-    defaults: ["VtsMediaC2V1_0Defaults"],
-    srcs: ["VtsHidlC2V1_0TargetComponentTest.cpp"],
+    name: "VtsHalMediaC2V1_0TargetComponentTest",
+    defaults: ["VtsHalMediaC2V1_0Defaults"],
+    srcs: ["VtsHalMediaC2V1_0TargetComponentTest.cpp"],
 }
 
diff --git a/media/codec2/hidl/1.0/vts/functional/component/VtsHidlC2V1_0TargetComponentTest.cpp b/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp
similarity index 100%
rename from media/codec2/hidl/1.0/vts/functional/component/VtsHidlC2V1_0TargetComponentTest.cpp
rename to media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp
diff --git a/media/codec2/hidl/1.0/vts/functional/master/Android.bp b/media/codec2/hidl/1.0/vts/functional/master/Android.bp
index e164d68..53e323e 100644
--- a/media/codec2/hidl/1.0/vts/functional/master/Android.bp
+++ b/media/codec2/hidl/1.0/vts/functional/master/Android.bp
@@ -15,8 +15,8 @@
  */
 
 cc_test {
-    name: "VtsHidlC2V1_0TargetMasterTest",
-    defaults: ["VtsMediaC2V1_0Defaults"],
-    srcs: ["VtsHidlC2V1_0TargetMasterTest.cpp"],
+    name: "VtsHalMediaC2V1_0TargetMasterTest",
+    defaults: ["VtsHalMediaC2V1_0Defaults"],
+    srcs: ["VtsHalMediaC2V1_0TargetMasterTest.cpp"],
 }
 
diff --git a/media/codec2/hidl/1.0/vts/functional/master/VtsHidlC2V1_0TargetMasterTest.cpp b/media/codec2/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp
similarity index 100%
rename from media/codec2/hidl/1.0/vts/functional/master/VtsHidlC2V1_0TargetMasterTest.cpp
rename to media/codec2/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp
diff --git a/media/codec2/hidl/1.0/vts/functional/video/Android.bp b/media/codec2/hidl/1.0/vts/functional/video/Android.bp
index 6e57ee7..b951306 100644
--- a/media/codec2/hidl/1.0/vts/functional/video/Android.bp
+++ b/media/codec2/hidl/1.0/vts/functional/video/Android.bp
@@ -15,14 +15,14 @@
  */
 
 cc_test {
-    name: "VtsHidlC2V1_0TargetVideoDecTest",
-    defaults: ["VtsMediaC2V1_0Defaults"],
-    srcs: ["VtsHidlC2V1_0TargetVideoDecTest.cpp"],
+    name: "VtsHalMeidaC2V1_0TargetVideoDecTest",
+    defaults: ["VtsHalMediaC2V1_0Defaults"],
+    srcs: ["VtsHalMediaC2V1_0TargetVideoDecTest.cpp"],
 }
 
 cc_test {
-    name: "VtsHidlC2V1_0TargetVideoEncTest",
-    defaults: ["VtsMediaC2V1_0Defaults"],
-    srcs: ["VtsHidlC2V1_0TargetVideoEncTest.cpp"],
+    name: "VtsHalMediaC2V1_0TargetVideoEncTest",
+    defaults: ["VtsHalMediaC2V1_0Defaults"],
+    srcs: ["VtsHalMediaC2V1_0TargetVideoEncTest.cpp"],
 }
 
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHidlC2V1_0TargetVideoDecTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
similarity index 100%
rename from media/codec2/hidl/1.0/vts/functional/video/VtsHidlC2V1_0TargetVideoDecTest.cpp
rename to media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHidlC2V1_0TargetVideoEncTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp
similarity index 100%
rename from media/codec2/hidl/1.0/vts/functional/video/VtsHidlC2V1_0TargetVideoEncTest.cpp
rename to media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp
diff --git a/media/codec2/sfplugin/C2OMXNode.cpp b/media/codec2/sfplugin/C2OMXNode.cpp
index 3a93c2a..d27fe32 100644
--- a/media/codec2/sfplugin/C2OMXNode.cpp
+++ b/media/codec2/sfplugin/C2OMXNode.cpp
@@ -36,6 +36,7 @@
 #include <media/stagefright/MediaErrors.h>
 #include <ui/Fence.h>
 #include <ui/GraphicBuffer.h>
+#include <utils/Thread.h>
 
 #include "C2OMXNode.h"
 
@@ -50,16 +51,126 @@
 
 }  // namespace
 
+class C2OMXNode::QueueThread : public Thread {
+public:
+    QueueThread() : Thread(false) {}
+    ~QueueThread() override = default;
+    void queue(
+            const std::shared_ptr<Codec2Client::Component> &comp,
+            int fenceFd,
+            std::unique_ptr<C2Work> &&work,
+            android::base::unique_fd &&fd0,
+            android::base::unique_fd &&fd1) {
+        Mutexed<Jobs>::Locked jobs(mJobs);
+        auto it = jobs->queues.try_emplace(comp, comp, systemTime()).first;
+        it->second.workList.emplace_back(
+                std::move(work), fenceFd, std::move(fd0), std::move(fd1));
+        jobs->cond.broadcast();
+    }
+
+protected:
+    bool threadLoop() override {
+        constexpr nsecs_t kIntervalNs = nsecs_t(10) * 1000 * 1000;  // 10ms
+        constexpr nsecs_t kWaitNs = kIntervalNs * 2;
+        for (int i = 0; i < 2; ++i) {
+            Mutexed<Jobs>::Locked jobs(mJobs);
+            nsecs_t nowNs = systemTime();
+            bool queued = false;
+            for (auto it = jobs->queues.begin(); it != jobs->queues.end(); ++it) {
+                Queue &queue = it->second;
+                if (queue.workList.empty()
+                        || nowNs - queue.lastQueuedTimestampNs < kIntervalNs) {
+                    continue;
+                }
+                std::shared_ptr<Codec2Client::Component> comp = queue.component.lock();
+                if (!comp) {
+                    it = jobs->queues.erase(it);
+                    continue;
+                }
+                std::list<std::unique_ptr<C2Work>> items;
+                std::vector<int> fenceFds;
+                std::vector<android::base::unique_fd> uniqueFds;
+                while (!queue.workList.empty()) {
+                    items.push_back(std::move(queue.workList.front().work));
+                    fenceFds.push_back(queue.workList.front().fenceFd);
+                    uniqueFds.push_back(std::move(queue.workList.front().fd0));
+                    uniqueFds.push_back(std::move(queue.workList.front().fd1));
+                    queue.workList.pop_front();
+                }
+
+                jobs.unlock();
+                for (int fenceFd : fenceFds) {
+                    sp<Fence> fence(new Fence(fenceFd));
+                    fence->waitForever(LOG_TAG);
+                }
+                comp->queue(&items);
+                for (android::base::unique_fd &ufd : uniqueFds) {
+                    (void)ufd.release();
+                }
+                jobs.lock();
+
+                queued = true;
+            }
+            if (queued) {
+                return true;
+            }
+            if (i == 0) {
+                jobs.waitForConditionRelative(jobs->cond, kWaitNs);
+            }
+        }
+        return true;
+    }
+
+private:
+    struct WorkFence {
+        WorkFence(std::unique_ptr<C2Work> &&w, int fd) : work(std::move(w)), fenceFd(fd) {}
+
+        WorkFence(
+                std::unique_ptr<C2Work> &&w,
+                int fd,
+                android::base::unique_fd &&uniqueFd0,
+                android::base::unique_fd &&uniqueFd1)
+            : work(std::move(w)),
+              fenceFd(fd),
+              fd0(std::move(uniqueFd0)),
+              fd1(std::move(uniqueFd1)) {}
+
+        std::unique_ptr<C2Work> work;
+        int fenceFd;
+        android::base::unique_fd fd0;
+        android::base::unique_fd fd1;
+    };
+    struct Queue {
+        Queue(const std::shared_ptr<Codec2Client::Component> &comp, nsecs_t timestamp)
+            : component(comp), lastQueuedTimestampNs(timestamp) {}
+        Queue(const Queue &) = delete;
+        Queue &operator =(const Queue &) = delete;
+
+        std::weak_ptr<Codec2Client::Component> component;
+        std::list<WorkFence> workList;
+        nsecs_t lastQueuedTimestampNs;
+    };
+    struct Jobs {
+        std::map<std::weak_ptr<Codec2Client::Component>,
+                 Queue,
+                 std::owner_less<std::weak_ptr<Codec2Client::Component>>> queues;
+        Condition cond;
+    };
+    Mutexed<Jobs> mJobs;
+};
+
 C2OMXNode::C2OMXNode(const std::shared_ptr<Codec2Client::Component> &comp)
     : mComp(comp), mFrameIndex(0), mWidth(0), mHeight(0), mUsage(0),
-      mAdjustTimestampGapUs(0), mFirstInputFrame(true) {
+      mAdjustTimestampGapUs(0), mFirstInputFrame(true),
+      mQueueThread(new QueueThread) {
     android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS);
+    mQueueThread->run("C2OMXNode", PRIORITY_AUDIO);
 }
 
 status_t C2OMXNode::freeNode() {
     mComp.reset();
     android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
-    return OK;
+    return mQueueThread->requestExitAndWait();
 }
 
 status_t C2OMXNode::sendCommand(OMX_COMMANDTYPE cmd, OMX_S32 param) {
@@ -216,11 +327,6 @@
 status_t C2OMXNode::emptyBuffer(
         buffer_id buffer, const OMXBuffer &omxBuf,
         OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
-    // TODO: better fence handling
-    if (fenceFd >= 0) {
-        sp<Fence> fence = new Fence(fenceFd);
-        fence->waitForever(LOG_TAG);
-    }
     std::shared_ptr<Codec2Client::Component> comp = mComp.lock();
     if (!comp) {
         return NO_INIT;
@@ -299,22 +405,8 @@
     }
     work->worklets.clear();
     work->worklets.emplace_back(new C2Worklet);
-    std::list<std::unique_ptr<C2Work>> items;
-    uint64_t index = work->input.ordinal.frameIndex.peeku();
-    items.push_back(std::move(work));
-
-    c2_status_t err = comp->queue(&items);
-    if (err != C2_OK) {
-        (void)fd0.release();
-        (void)fd1.release();
-        return UNKNOWN_ERROR;
-    }
-
-    mBufferIdsInUse.lock()->emplace(index, buffer);
-
-    // release ownership of the fds
-    (void)fd0.release();
-    (void)fd1.release();
+    mBufferIdsInUse.lock()->emplace(work->input.ordinal.frameIndex.peeku(), buffer);
+    mQueueThread->queue(comp, fenceFd, std::move(work), std::move(fd0), std::move(fd1));
 
     return OK;
 }
diff --git a/media/codec2/sfplugin/C2OMXNode.h b/media/codec2/sfplugin/C2OMXNode.h
index 3ca6c0a..1717c96 100644
--- a/media/codec2/sfplugin/C2OMXNode.h
+++ b/media/codec2/sfplugin/C2OMXNode.h
@@ -113,6 +113,9 @@
     c2_cntr64_t mPrevCodecTimestamp; // adjusted (codec) timestamp for previous frame
 
     Mutexed<std::map<uint64_t, buffer_id>> mBufferIdsInUse;
+
+    class QueueThread;
+    sp<QueueThread> mQueueThread;
 };
 
 }  // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 2cd920a..4653711 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -1578,7 +1578,7 @@
         }
 
         if (mPreparing) {
-            notifyPreparedAndCleanup(finalStatus);
+            notifyPreparedAndCleanup(finalStatus == ERROR_END_OF_STREAM ? OK : finalStatus);
             mPreparing = false;
         } else if (mSentPauseOnBuffering) {
             sendCacheStats();
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/packet_util.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/packet_util.cpp
index 48414d7..5880e32 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/packet_util.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/packet_util.cpp
@@ -52,7 +52,11 @@
         PV_BitstreamByteAlign(stream);
         BitstreamReadBits32(stream, resync_marker_length);
 
-        *next_MB = (int) BitstreamReadBits16(stream, nbits);
+        int mbnum = (int) BitstreamReadBits16(stream, nbits);
+        if (mbnum < 0) {
+            return PV_FAIL;
+        }
+        *next_MB = mbnum;
 //      if (*next_MB <= video->mbnum)   /*  needs more investigation */
 //          *next_MB = video->mbnum+1;