Skip to content

Commit

Permalink
[c2][store] Add concurrent-instances support and fixed cts failures
Browse files Browse the repository at this point in the history
cases:
testLowerPriorityProcessFailsToReclaimResources
testHigherPriorityProcessReclaimsResources

* The creating component instances of the same type can't exceece
the configured the number of maximum concurrent instances.
* The default value is 32, you can configure it
in xml file if you want.
(e.g. `<Limit name="concurrent-instances" max="16" />`)

Tracked-On: OAM-117234
Signed-off-by: zhangyichix <[email protected]>
  • Loading branch information
zhangyichix committed Apr 11, 2024
1 parent 7210e66 commit a273735
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 0 deletions.
1 change: 1 addition & 0 deletions c2_components/include/mfx_c2_component.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class MfxC2Component : public C2ComponentInterface,
{
int flags{0};
bool dump_output{false};
uint32_t concurrent_instances{0};
};
protected:
/* State diagram:
Expand Down
17 changes: 17 additions & 0 deletions c2_components/src/mfx_c2_component.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "mfx_debug.h"
#include "mfx_c2_debug.h"
#include "mfx_c2_components_registry.h"
#include "mfx_c2_components_monitor.h"

using namespace android;

Expand Down Expand Up @@ -303,6 +304,17 @@ c2_status_t MfxC2Component::start()
MFX_DEBUG_TRACE_FUNC;

c2_status_t res = C2_OK;

MfxC2ComponentsMonitor::getInstance().increase(m_name.c_str());

// The creating component instances of the same type can't exceece the configured the number of maximum concurrent instances
// And must ensure that C2_NO_MEMORY is returned by start() which because the reclaimResource calling happens in
// MediaCodec::start() in libstagefright
MFX_DEBUG_TRACE_I32(m_createConfig.concurrent_instances);
if (MfxC2ComponentsMonitor::getInstance().get(m_name.c_str()) > m_createConfig.concurrent_instances) {
MFX_DEBUG_TRACE_MSG("Cannot create component, the number of created components has exceeded maximum instance limit.");
return C2_NO_MEMORY;
}
// work to be done for state change
std::function<c2_status_t()> action = [] () { return C2_CORRUPTED; };

Expand Down Expand Up @@ -339,6 +351,8 @@ c2_status_t MfxC2Component::start()
}
m_condStateStable.notify_all();
}
} else {
MfxC2ComponentsMonitor::getInstance().decrease(m_name.c_str());
}

MFX_DEBUG_TRACE__android_c2_status_t(res);
Expand Down Expand Up @@ -449,6 +463,9 @@ c2_status_t MfxC2Component::release()
}
}

if (C2_OK == res) {
MfxC2ComponentsMonitor::getInstance().decrease(m_name.c_str());
}
MFX_DEBUG_TRACE__android_c2_status_t(res);
return res;
}
Expand Down
1 change: 1 addition & 0 deletions c2_store/src/mfx_c2_store.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ c2_status_t MfxC2ComponentStore::readConfigFile()
MfxC2Component::CreateConfig config;
config.flags = flags;
config.dump_output = m_xmlParser.dumpOutputEnabled(name.c_str());
config.concurrent_instances = m_xmlParser.getConcurrentInstances(name.c_str());

m_componentsRegistry_.emplace(name, ComponentDesc(module.c_str(), media_type.c_str(), kind, config));
}
Expand Down
48 changes: 48 additions & 0 deletions c2_utils/include/mfx_c2_components_monitor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) 2017-2023 Intel Corporation
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#pragma once

#include <string>
#include <map>
#include <mutex>
#include "mfx_defs.h"

class MfxC2ComponentsMonitor
{
private:
MfxC2ComponentsMonitor() {}
public:
MFX_CLASS_NO_COPY(MfxC2ComponentsMonitor);

static MfxC2ComponentsMonitor& getInstance()
{
static MfxC2ComponentsMonitor m_pInstance;
return m_pInstance;
}

unsigned int get(std::string name);
void increase(std::string name);
void decrease(std::string name);

private:
std::map<std::string, unsigned int> m_monitor;
std::mutex m_mutex;
};
4 changes: 4 additions & 0 deletions c2_utils/include/mfx_c2_xml_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class MfxXmlParser
c2_status_t parseConfig(const char *path);
C2Component::kind_t getKind(const char *name);
C2String getMediaType(const char *name);
uint32_t getConcurrentInstances(const char *name);
bool dumpOutputEnabled(const char *name);

private:
Expand All @@ -60,6 +61,7 @@ class MfxXmlParser
size_t order; // order of appearance in the file (starting from 0)
std::map<C2String, AttributeMap> typeMap; // map of types supported by this codec
bool dump_output{false};
uint32_t concurrentInstance{0};
};

enum Section {
Expand All @@ -79,6 +81,8 @@ class MfxXmlParser

c2_status_t addDiagnostics(const char **attrs);

c2_status_t addLimits(const char **attrs);

void startElementHandler(const char *name, const char **attrs);
void endElementHandler(const char *name);

Expand Down
2 changes: 2 additions & 0 deletions c2_utils/include/mfx_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ extern mfxVersion g_required_mfx_version;
#include <va/va.h>
#endif // #ifdef LIBVA_SUPPORT

constexpr uint32_t DEFAULT_MAX_INSTANCES = 32;

#define MFX_MAX_PATH 260

#define WIDTH_16K 16384
Expand Down
78 changes: 78 additions & 0 deletions c2_utils/src/mfx_c2_components_monitor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright (c) 2017-2023 Intel Corporation
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include "mfx_c2_components_monitor.h"
#include "mfx_c2_debug.h"

#undef MFX_DEBUG_MODULE_NAME
#define MFX_DEBUG_MODULE_NAME "mfx_c2_components_monitor"

uint32_t MfxC2ComponentsMonitor::get(std::string name)
{
MFX_DEBUG_TRACE_FUNC;

std::unique_lock<std::mutex> lock(m_mutex);
auto obj = m_monitor.find(name);
if (m_monitor.end() != obj)
{
MFX_DEBUG_TRACE_I32(obj->second);
return obj->second;
}
return 0;
}

void MfxC2ComponentsMonitor::increase(std::string name)
{
MFX_DEBUG_TRACE_FUNC;

std::unique_lock<std::mutex> lock(m_mutex);
auto obj = m_monitor.find(name);
if (m_monitor.end() == obj)
{
MFX_DEBUG_TRACE_STREAM("increase " << name << ", instances 0 + 1");
m_monitor.insert(std::pair<std::string, uint32_t>(name, 1));
}
else
{
MFX_DEBUG_TRACE_STREAM("increase " << name << ", instances " << obj->second << " + 1");
obj->second++;
}
}

void MfxC2ComponentsMonitor::decrease(std::string name)
{
MFX_DEBUG_TRACE_FUNC;

std::unique_lock<std::mutex> lock(m_mutex);
auto obj = m_monitor.find(name);
if (m_monitor.end() == obj) // impossible
{
MFX_DEBUG_TRACE_MSG("can't find the record!");
m_monitor.insert(std::pair<std::string, uint32_t>(name, 0));
}
else
{
MFX_DEBUG_TRACE_STREAM("decrease " << name << ", instances " << obj->second << " - 1");
if (0 == obj->second)
obj->second = 0;
else
obj->second--;
}
}
34 changes: 34 additions & 0 deletions c2_utils/src/mfx_c2_xml_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
*/

#include "mfx_c2_xml_parser.h"
#include "mfx_defs.h"
#include "mfx_c2_debug.h"
#include <expat.h>

Expand Down Expand Up @@ -81,6 +82,18 @@ C2Component::kind_t MfxXmlParser::getKind(const char *name) {
return codec->second.isEncoder ? KIND_ENCODER : KIND_DECODER;
}

uint32_t MfxXmlParser::getConcurrentInstances(const char *name) {
MFX_DEBUG_TRACE_FUNC;

auto codec = m_codecMap.find(name);
if (codec == m_codecMap.end() || 0 == codec->second.concurrentInstance) {
MFX_DEBUG_TRACE_STREAM("concurrent-instances wasn't found, using default value " << DEFAULT_MAX_INSTANCES);
return DEFAULT_MAX_INSTANCES;
}

return codec->second.concurrentInstance;
}

bool MfxXmlParser::dumpOutputEnabled(const char *name) {

MFX_DEBUG_TRACE_FUNC;
Expand Down Expand Up @@ -177,6 +190,25 @@ c2_status_t MfxXmlParser::addDiagnostics(const char **attrs) {
return C2_OK;
}

c2_status_t MfxXmlParser::addLimits(const char **attrs) {
MFX_DEBUG_TRACE_FUNC;
size_t i = 0;
while (attrs[i] != nullptr) {
if (strcmp(attrs[i], "concurrent-instances") == 0) {
if (strcmp(attrs[++i], "max") == 0) {
m_currentCodec->second.concurrentInstance = std::atoi(attrs[++i]);
MFX_DEBUG_TRACE_STREAM("m_currentCodec->second.concurrentInstance = %d", m_currentCodec->second.concurrentInstance);
} else {
MFX_DEBUG_TRACE_MSG("concurrent-instances is null");
return C2_BAD_VALUE;
}
}
i++;
}

return C2_OK;
}

void MfxXmlParser::startElementHandler(const char* name, const char** attrs) {

MFX_DEBUG_TRACE_FUNC;
Expand Down Expand Up @@ -233,6 +265,8 @@ void MfxXmlParser::startElementHandler(const char* name, const char** attrs) {
if (strcmp(name, "Diagnostics") == 0) {
m_parsingStatus =
addDiagnostics(attrs);
} else if (strcmp(name, "Limit") == 0) {
addLimits(attrs);
}
break;
}
Expand Down

0 comments on commit a273735

Please sign in to comment.