Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1c8e6821 authored by Pawin Vongmasa's avatar Pawin Vongmasa
Browse files

Upstream changes from Codec2 MTS

This includes changes up to commit
b3c2c12135ad6e96ca3cfa258bba24eb7b7b92ca.

Test: Builds

Bug: 112362730
Bug: 119853704
Change-Id: I97adbe52258d72d18446f12a9698462174e89b19
parent 980af763
Loading
Loading
Loading
Loading
+117 −144
Original line number Diff line number Diff line
@@ -156,33 +156,7 @@ class Codec2AudioDecHidlTest : public ::testing::VtsHalHidlTargetTestBase {
    // callback function to process onWorkDone received by Listener
    void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
        for (std::unique_ptr<C2Work>& work : workItems) {
            // handle configuration changes in work done
            if (!work->worklets.empty() &&
                (work->worklets.front()->output.configUpdate.size() != 0)) {
                ALOGV("Config Update");
                std::vector<std::unique_ptr<C2Param>> updates =
                    std::move(work->worklets.front()->output.configUpdate);
                std::vector<C2Param*> configParam;
                std::vector<std::unique_ptr<C2SettingResult>> failures;
                for (size_t i = 0; i < updates.size(); ++i) {
                    C2Param* param = updates[i].get();
                    if ((param->index() == C2StreamSampleRateInfo::output::PARAM_TYPE) ||
                        (param->index() == C2StreamChannelCountInfo::output::PARAM_TYPE)) {
                        configParam.push_back(param);
                    }
                }
                mComponent->config(configParam, C2_DONT_BLOCK, &failures);
                ASSERT_EQ(failures.size(), 0u);
            }
            mFramesReceived++;
            mEos = (work->worklets.front()->output.flags &
                    C2FrameData::FLAG_END_OF_STREAM) != 0;
            auto frameIndexIt =
                std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
                          work->input.ordinal.frameIndex.peeku());
            ALOGV("WorkDone: frameID received %d",
                (int)work->worklets.front()->output.ordinal.frameIndex.peeku());

            if (!work->worklets.empty()) {
                // For decoder components current timestamp always exceeds
                // previous timestamp
                bool codecConfig = ((work->worklets.front()->output.flags &
@@ -202,17 +176,11 @@ class Codec2AudioDecHidlTest : public ::testing::VtsHalHidlTargetTestBase {
                        oBufferMetaData.push_back(meta);
                    }
                }

            work->input.buffers.clear();
            work->worklets.clear();
            {
                typedef std::unique_lock<std::mutex> ULock;
                ULock l(mQueueLock);
                mWorkQueue.push_back(std::move(work));
                if (!mFlushedIndices.empty()) {
                    mFlushedIndices.erase(frameIndexIt);
                }
                mQueueCondition.notify_all();
                bool mCsd = false;
                workDone(mComponent, work, mFlushedIndices, mQueueLock,
                         mQueueCondition, mWorkQueue, mEos, mCsd,
                         mFramesReceived);
                (void)mCsd;
            }
        }
    }
@@ -462,10 +430,13 @@ void decodeNFrames(const std::shared_ptr<android::Codec2Client::Component> &comp
        }
        int size = (*Info)[frameID].bytesCount;
        char* data = (char*)malloc(size);
        ASSERT_NE(data, nullptr);

        eleStream.read(data, size);
        ASSERT_EQ(eleStream.gcount(), size);

        work->input.buffers.clear();
        if (size) {
            std::shared_ptr<C2LinearBlock> block;
            ASSERT_EQ(C2_OK,
                    linearPool->fetchLinearBlock(
@@ -485,11 +456,11 @@ void decodeNFrames(const std::shared_ptr<android::Codec2Client::Component> &comp

            memcpy(view.base(), data, size);

        work->input.buffers.clear();
            work->input.buffers.emplace_back(new LinearBuffer(block));
            free(data);
        }
        work->worklets.clear();
        work->worklets.emplace_back(new C2Worklet);
        free(data);

        std::list<std::unique_ptr<C2Work>> items;
        items.push_back(std::move(work));
@@ -502,29 +473,6 @@ void decodeNFrames(const std::shared_ptr<android::Codec2Client::Component> &comp
    }
}

void waitOnInputConsumption(std::mutex& queueLock,
                            std::condition_variable& queueCondition,
                            std::list<std::unique_ptr<C2Work>>& workQueue,
                            size_t bufferCount = MAX_INPUT_BUFFERS) {
    typedef std::unique_lock<std::mutex> ULock;
    uint32_t queueSize;
    uint32_t maxRetry = 0;
    {
        ULock l(queueLock);
        queueSize = workQueue.size();
    }
    while ((maxRetry < MAX_RETRY) && (queueSize < bufferCount)) {
        ULock l(queueLock);
        if (queueSize != workQueue.size()) {
            queueSize = workQueue.size();
            maxRetry = 0;
        } else {
            queueCondition.wait_for(l, TIME_OUT);
            maxRetry++;
        }
    }
}

TEST_F(Codec2AudioDecHidlTest, validateCompName) {
    if (mDisableTest) return;
    ALOGV("Checks if the given component is a valid audio component");
@@ -718,7 +666,6 @@ TEST_F(Codec2AudioDecHidlTest, EOSTest) {
    ASSERT_EQ(mComponent->queue(&items), C2_OK);

    {
        typedef std::unique_lock<std::mutex> ULock;
        ULock l(mQueueLock);
        if (mWorkQueue.size() != MAX_INPUT_BUFFERS) {
            mQueueCondition.wait_for(l, TIME_OUT);
@@ -729,46 +676,6 @@ TEST_F(Codec2AudioDecHidlTest, EOSTest) {
    ASSERT_EQ(mComponent->stop(), C2_OK);
}

TEST_F(Codec2AudioDecHidlTest, EmptyBufferTest) {
    description("Tests empty input buffer");
    if (mDisableTest) return;
    typedef std::unique_lock<std::mutex> ULock;
    ASSERT_EQ(mComponent->start(), C2_OK);
    std::unique_ptr<C2Work> work;
    // Prepare C2Work
    {
        ULock l(mQueueLock);
        if (!mWorkQueue.empty()) {
            work.swap(mWorkQueue.front());
            mWorkQueue.pop_front();
        } else {
            ASSERT_TRUE(false) << "mWorkQueue Empty at the start of test";
        }
    }
    ASSERT_NE(work, nullptr);

    work->input.flags = (C2FrameData::flags_t)0;
    work->input.ordinal.timestamp = 0;
    work->input.ordinal.frameIndex = 0;
    work->input.buffers.clear();
    work->worklets.clear();
    work->worklets.emplace_back(new C2Worklet);

    std::list<std::unique_ptr<C2Work>> items;
    items.push_back(std::move(work));
    ASSERT_EQ(mComponent->queue(&items), C2_OK);

    {
        typedef std::unique_lock<std::mutex> ULock;
        ULock l(mQueueLock);
        if (mWorkQueue.size() != MAX_INPUT_BUFFERS) {
            mQueueCondition.wait_for(l, TIME_OUT);
        }
    }
    ASSERT_EQ(mWorkQueue.size(), (size_t)MAX_INPUT_BUFFERS);
    ASSERT_EQ(mComponent->stop(), C2_OK);
}

TEST_F(Codec2AudioDecHidlTest, FlushTest) {
    description("Tests Flush calls");
    if (mDisableTest) return;
@@ -891,6 +798,72 @@ TEST_F(Codec2AudioDecHidlTest, FlushTest) {
    ASSERT_EQ(mComponent->stop(), C2_OK);
}

TEST_F(Codec2AudioDecHidlTest, DecodeTestEmptyBuffersInserted) {
    description("Decode with multiple empty input frames");
    if (mDisableTest) return;

    ASSERT_EQ(mComponent->start(), C2_OK);

    char mURL[512], info[512];
    std::ifstream eleStream, eleInfo;

    strcpy(mURL, gEnv->getRes().c_str());
    strcpy(info, gEnv->getRes().c_str());
    GetURLForComponent(mCompName, mURL, info);

    eleInfo.open(info);
    ASSERT_EQ(eleInfo.is_open(), true) << mURL << " - file not found";
    android::Vector<FrameInfo> Info;
    int bytesCount = 0;
    uint32_t frameId = 0;
    uint32_t flags = 0;
    uint32_t timestamp = 0;
    bool codecConfig = false;
    // This test introduces empty CSD after every 20th frame
    // and empty input frames at an interval of 5 frames.
    while (1) {
        if (!(frameId % 5)) {
            if (!(frameId % 20)) flags = 32;
            else flags = 0;
            bytesCount = 0;
        } else {
            if (!(eleInfo >> bytesCount)) break;
            eleInfo >> flags;
            eleInfo >> timestamp;
            codecConfig = flags ?
                ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0;
        }
        Info.push_back({bytesCount, flags, timestamp});
        frameId++;
    }
    eleInfo.close();

    ALOGV("mURL : %s", mURL);
    eleStream.open(mURL, std::ifstream::binary);
    ASSERT_EQ(eleStream.is_open(), true);
    ASSERT_NO_FATAL_FAILURE(decodeNFrames(
        mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices,
        mLinearPool, eleStream, &Info, 0, (int)Info.size()));

    // blocking call to ensures application to Wait till all the inputs are
    // consumed
    if (!mEos) {
        ALOGV("Waiting for input consumption");
        ASSERT_NO_FATAL_FAILURE(
            waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
    }

    eleStream.close();
    if (mFramesReceived != Info.size()) {
        ALOGE("Input buffer count and Output buffer count mismatch");
        ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived,
              Info.size());
        ASSERT_TRUE(false);
    }

    ASSERT_EQ(mComponent->stop(), C2_OK);
}

}  // anonymous namespace

int main(int argc, char** argv) {
+25 −102
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ class Codec2AudioEncHidlTest : public ::testing::VtsHalHidlTargetTestBase {
        const StringToName kStringToName[] = {
            {"aac", aac},
            {"flac", flac},
            {"opus", opus},
            {"amrnb", amrnb},
            {"amrwb", amrwb},
        };
@@ -135,45 +136,17 @@ class Codec2AudioEncHidlTest : public ::testing::VtsHalHidlTargetTestBase {
    // callback function to process onWorkDone received by Listener
    void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
        for (std::unique_ptr<C2Work>& work : workItems) {
            // handle configuration changes in work done
            if (!work->worklets.empty() &&
                (work->worklets.front()->output.configUpdate.size() != 0)) {
                ALOGV("Config Update");
                std::vector<std::unique_ptr<C2Param>> updates =
                    std::move(work->worklets.front()->output.configUpdate);
                std::vector<C2Param*> configParam;
                std::vector<std::unique_ptr<C2SettingResult>> failures;
                for (size_t i = 0; i < updates.size(); ++i) {
                    C2Param* param = updates[i].get();
                    if (param->index() == C2StreamCsdInfo::output::PARAM_TYPE) {
                        mCsd = true;
                    }
                }
            }
            mFramesReceived++;
            mEos = (work->worklets.front()->output.flags &
                    C2FrameData::FLAG_END_OF_STREAM) != 0;
            auto frameIndexIt =
                std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
                          work->input.ordinal.frameIndex.peeku());
            ALOGV("WorkDone: frameID received %d",
                (int)work->worklets.front()->output.ordinal.frameIndex.peeku());
            work->input.buffers.clear();
            work->worklets.clear();
            {
                typedef std::unique_lock<std::mutex> ULock;
                ULock l(mQueueLock);
                mWorkQueue.push_back(std::move(work));
                if (!mFlushedIndices.empty()) {
                    mFlushedIndices.erase(frameIndexIt);
                }
                mQueueCondition.notify_all();
            if (!work->worklets.empty()) {
                workDone(mComponent, work, mFlushedIndices, mQueueLock,
                         mQueueCondition, mWorkQueue, mEos, mCsd,
                         mFramesReceived);
            }
        }
    }
    enum standardComp {
        aac,
        flac,
        opus,
        amrnb,
        amrwb,
        unknown_comp,
@@ -275,6 +248,8 @@ void GetURLForComponent(Codec2AudioEncHidlTest::standardComp comp, char* mURL) {
         "bbb_raw_1ch_16khz_s16le.raw"},
        {Codec2AudioEncHidlTest::standardComp::flac,
         "bbb_raw_2ch_48khz_s16le.raw"},
        {Codec2AudioEncHidlTest::standardComp::opus,
         "bbb_raw_2ch_48khz_s16le.raw"},
    };

    for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
@@ -334,6 +309,7 @@ void encodeNFrames(const std::shared_ptr<android::Codec2Client::Component> &comp
            flushedIndices.emplace_back(frameID);
        }
        char* data = (char*)malloc(bytesCount);
        ASSERT_NE(data, nullptr);
        eleStream.read(data, bytesCount);
        ASSERT_EQ(eleStream.gcount(), bytesCount);
        std::shared_ptr<C2LinearBlock> block;
@@ -372,29 +348,6 @@ void encodeNFrames(const std::shared_ptr<android::Codec2Client::Component> &comp
    }
}

void waitOnInputConsumption(std::mutex& queueLock,
                            std::condition_variable& queueCondition,
                            std::list<std::unique_ptr<C2Work>>& workQueue,
                            size_t bufferCount = MAX_INPUT_BUFFERS) {
    typedef std::unique_lock<std::mutex> ULock;
    uint32_t queueSize;
    uint32_t maxRetry = 0;
    {
        ULock l(queueLock);
        queueSize = workQueue.size();
    }
    while ((maxRetry < MAX_RETRY) && (queueSize < bufferCount)) {
        ULock l(queueLock);
        if (queueSize != workQueue.size()) {
            queueSize = workQueue.size();
            maxRetry = 0;
        } else {
            queueCondition.wait_for(l, TIME_OUT);
            maxRetry++;
        }
    }
}

TEST_F(Codec2AudioEncHidlTest, validateCompName) {
    if (mDisableTest) return;
    ALOGV("Checks if the given component is a valid audio component");
@@ -425,6 +378,11 @@ TEST_F(Codec2AudioEncHidlTest, EncodeTest) {
            nSampleRate = 48000;
            samplesPerFrame = 1152;
            break;
        case opus:
            nChannels = 2;
            nSampleRate = 48000;
            samplesPerFrame = 960;
            break;
        case amrnb:
            nChannels = 1;
            nSampleRate = 8000;
@@ -458,7 +416,7 @@ TEST_F(Codec2AudioEncHidlTest, EncodeTest) {
        ALOGE("framesReceived : %d inputFrames : %u", mFramesReceived, numFrames);
        ASSERT_TRUE(false);
    }
    if ((mCompName == flac || mCompName == aac)) {
    if ((mCompName == flac || mCompName == opus || mCompName == aac)) {
        if (!mCsd) {
            ALOGE("CSD buffer missing");
            ASSERT_TRUE(false);
@@ -508,46 +466,6 @@ TEST_F(Codec2AudioEncHidlTest, EOSTest) {
    ASSERT_EQ(mComponent->stop(), C2_OK);
}

TEST_F(Codec2AudioEncHidlTest, EmptyBufferTest) {
    description("Tests empty input buffer");
    if (mDisableTest) return;
    ASSERT_EQ(mComponent->start(), C2_OK);

    typedef std::unique_lock<std::mutex> ULock;
    std::unique_ptr<C2Work> work;
    {
        ULock l(mQueueLock);
        if (!mWorkQueue.empty()) {
            work.swap(mWorkQueue.front());
            mWorkQueue.pop_front();
        } else {
            ALOGE("mWorkQueue Empty is not expected at the start of the test");
            ASSERT_TRUE(false);
        }
    }
    ASSERT_NE(work, nullptr);
    work->input.flags = (C2FrameData::flags_t)0;
    work->input.ordinal.timestamp = 0;
    work->input.ordinal.frameIndex = 0;
    work->input.buffers.clear();
    work->worklets.clear();
    work->worklets.emplace_back(new C2Worklet);

    std::list<std::unique_ptr<C2Work>> items;
    items.push_back(std::move(work));
    ASSERT_EQ(mComponent->queue(&items), C2_OK);
    uint32_t queueSize;
    {
        ULock l(mQueueLock);
        queueSize = mWorkQueue.size();
        if (queueSize < MAX_INPUT_BUFFERS) {
            mQueueCondition.wait_for(l, TIME_OUT);
        }
    }
    ASSERT_EQ(mWorkQueue.size(), (uint32_t)MAX_INPUT_BUFFERS);
    ASSERT_EQ(mComponent->stop(), C2_OK);
}

TEST_F(Codec2AudioEncHidlTest, FlushTest) {
    description("Test Request for flush");
    if (mDisableTest) return;
@@ -574,6 +492,11 @@ TEST_F(Codec2AudioEncHidlTest, FlushTest) {
            nSampleRate = 48000;
            samplesPerFrame = 1152;
            break;
        case opus:
            nChannels = 2;
            nSampleRate = 48000;
            samplesPerFrame = 960;
            break;
        case amrnb:
            nChannels = 1;
            nSampleRate = 8000;
+0 −3
Original line number Diff line number Diff line
@@ -17,8 +17,5 @@
#ifndef MEDIA_C2_AUDIO_HIDL_TEST_COMMON_H
#define MEDIA_C2_AUDIO_HIDL_TEST_COMMON_H

#define MAX_RETRY 20
#define TIME_OUT 200ms
#define MAX_INPUT_BUFFERS 8

#endif  // MEDIA_C2_AUDIO_HIDL_TEST_COMMON_H
+101 −25
Original line number Diff line number Diff line
@@ -14,39 +14,115 @@
 * limitations under the License.
 */

// #define LOG_NDEBUG 0
#define LOG_TAG "media_c2_hidl_test_common"
#include <stdio.h>

#include "media_c2_hidl_test_common.h"
using ::android::hardware::media::c2::V1_0::FieldSupportedValues;

void dumpFSV(const FieldSupportedValues& sv) {
    ALOGD("Dumping FSV data");
    using namespace std;
    if (sv.type == FieldSupportedValues::Type::EMPTY) {
        ALOGD("FSV Value is Empty");
    }
    if (sv.type == FieldSupportedValues::Type::RANGE) {
        ALOGD("Dumping FSV range");
        cout << ".range(" << sv.range.min;
        if (sv.range.step != 0) {
            cout << ":" << sv.range.step;
        }
        if (sv.range.num != 1 || sv.range.denom != 1) {
            cout << ":" << sv.range.num << "/" << sv.range.denom;
        }
        cout << " " << sv.range.max << ")";
    }
    if (sv.values.size()) {
        ALOGD("Dumping FSV value");
        cout << (sv.type == FieldSupportedValues::Type::FLAGS ? ".flags("
                                                              : ".list(");
        const char* sep = "";
        for (const auto& p : sv.values) {
            cout << sep << p;
            sep = ",";
        }
        cout << ")";
    }
    cout << endl;
// Test the codecs for NullBuffer, Empty Input Buffer with(out) flags set
void testInputBuffer(
    const std::shared_ptr<android::Codec2Client::Component>& component,
    std::mutex& queueLock, std::list<std::unique_ptr<C2Work>>& workQueue,
    uint32_t flags, bool isNullBuffer) {
    std::unique_ptr<C2Work> work;
    {
        typedef std::unique_lock<std::mutex> ULock;
        ULock l(queueLock);
        if (!workQueue.empty()) {
            work.swap(workQueue.front());
            workQueue.pop_front();
        } else {
            ASSERT_TRUE(false) << "workQueue Empty at the start of test";
        }
    }
    ASSERT_NE(work, nullptr);

    work->input.flags = (C2FrameData::flags_t)flags;
    work->input.ordinal.timestamp = 0;
    work->input.ordinal.frameIndex = 0;
    work->input.buffers.clear();
    if (isNullBuffer) {
        work->input.buffers.emplace_back(nullptr);
    }
    work->worklets.clear();
    work->worklets.emplace_back(new C2Worklet);

    std::list<std::unique_ptr<C2Work>> items;
    items.push_back(std::move(work));
    ASSERT_EQ(component->queue(&items), C2_OK);
}

// Wait for all the inputs to be consumed by the plugin.
void waitOnInputConsumption(std::mutex& queueLock,
                            std::condition_variable& queueCondition,
                            std::list<std::unique_ptr<C2Work>>& workQueue,
                            size_t bufferCount) {
    typedef std::unique_lock<std::mutex> ULock;
    uint32_t queueSize;
    uint32_t maxRetry = 0;
    {
        ULock l(queueLock);
        queueSize = workQueue.size();
    }
    while ((maxRetry < MAX_RETRY) && (queueSize < bufferCount)) {
        ULock l(queueLock);
        if (queueSize != workQueue.size()) {
            queueSize = workQueue.size();
            maxRetry = 0;
        } else {
            queueCondition.wait_for(l, TIME_OUT);
            maxRetry++;
        }
    }
}

// process onWorkDone received by Listener
void workDone(
    const std::shared_ptr<android::Codec2Client::Component>& component,
    std::unique_ptr<C2Work>& work, std::list<uint64_t>& flushedIndices,
    std::mutex& queueLock, std::condition_variable& queueCondition,
    std::list<std::unique_ptr<C2Work>>& workQueue, bool& eos, bool& csd,
    uint32_t& framesReceived) {
    // handle configuration changes in work done
    if (work->worklets.front()->output.configUpdate.size() != 0) {
        ALOGV("Config Update");
        std::vector<std::unique_ptr<C2Param>> updates =
            std::move(work->worklets.front()->output.configUpdate);
        std::vector<C2Param*> configParam;
        std::vector<std::unique_ptr<C2SettingResult>> failures;
        for (size_t i = 0; i < updates.size(); ++i) {
            C2Param* param = updates[i].get();
            if (param->index() == C2StreamCsdInfo::output::PARAM_TYPE) {
                csd = true;
            } else if ((param->index() ==
                        C2StreamSampleRateInfo::output::PARAM_TYPE) ||
                       (param->index() ==
                        C2StreamChannelCountInfo::output::PARAM_TYPE) ||
                       (param->index() ==
                        C2VideoSizeStreamInfo::output::PARAM_TYPE)) {
                configParam.push_back(param);
            }
        }
        component->config(configParam, C2_DONT_BLOCK, &failures);
        ASSERT_EQ(failures.size(), 0u);
    }
    framesReceived++;
    eos = (work->worklets.front()->output.flags &
           C2FrameData::FLAG_END_OF_STREAM) != 0;
    auto frameIndexIt = std::find(flushedIndices.begin(), flushedIndices.end(),
                                  work->input.ordinal.frameIndex.peeku());
    ALOGV("WorkDone: frameID received %d",
          (int)work->worklets.front()->output.ordinal.frameIndex.peeku());
    work->input.buffers.clear();
    work->worklets.clear();
    {
        typedef std::unique_lock<std::mutex> ULock;
        ULock l(queueLock);
        workQueue.push_back(std::move(work));
        if (!flushedIndices.empty()) {
            flushedIndices.erase(frameIndexIt);
        }
        queueCondition.notify_all();
    }
}
 No newline at end of file
+22 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <android/hardware/media/c2/1.0/types.h>

#include <C2Component.h>
#include <C2Config.h>
#include <getopt.h>
#include <hidl/HidlSupport.h>
#include <media/stagefright/foundation/ALooper.h>
@@ -38,6 +39,10 @@ using ::android::hardware::hidl_string;

#include <VtsHalHidlTargetTestEnvBase.h>

#define MAX_RETRY 20
#define TIME_OUT 400ms
#define MAX_INPUT_BUFFERS 8

/*
 * Handle Callback functions onWorkDone(), onTripped(),
 * onError(), onDeath(), onFramesRendered()
@@ -176,5 +181,21 @@ class ComponentTestEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
/*
 * common functions declarations
 */
void dumpFSV(const FieldSupportedValues& sv);
void testInputBuffer(
    const std::shared_ptr<android::Codec2Client::Component>& component,
    std::mutex& queueLock, std::list<std::unique_ptr<C2Work>>& workQueue,
    uint32_t flags, bool isNullBuffer);

void waitOnInputConsumption(std::mutex& queueLock,
                            std::condition_variable& queueCondition,
                            std::list<std::unique_ptr<C2Work>>& workQueue,
                            size_t bufferCount = MAX_INPUT_BUFFERS);

void workDone(
    const std::shared_ptr<android::Codec2Client::Component>& component,
    std::unique_ptr<C2Work>& work, std::list<uint64_t>& flushedIndices,
    std::mutex& queueLock, std::condition_variable& queueCondition,
    std::list<std::unique_ptr<C2Work>>& workQueue, bool& eos, bool& csd,
    uint32_t& framesReceived);

#endif  // MEDIA_C2_HIDL_TEST_COMMON_H
Loading