mirror of
https://github.com/openharmony/multimedia_audio_standard.git
synced 2026-07-01 22:14:07 -04:00
Handle test mode with sysprop and fix video resume hang issue
Signed-off-by: Vaidegi B <vaidegi.b1@huawei.com>
This commit is contained in:
@@ -51,7 +51,6 @@ ohos_shared_library("module-hdi-sink") {
|
||||
configs = [ ":hdi_config" ]
|
||||
|
||||
cflags = [ "-DPA_MODULE_NAME=libmodule_hdi_sink_z_so" ]
|
||||
cflags += [ "-DTEST_MODE" ]
|
||||
|
||||
ldflags = [
|
||||
"-Wl",
|
||||
|
||||
@@ -79,10 +79,9 @@ struct Userdata {
|
||||
struct RendererSinkAdapter *sinkAdapter;
|
||||
pa_asyncmsgq *dq;
|
||||
pa_atomic_t dflag;
|
||||
#ifdef TEST_MODE
|
||||
bool test_mode_on;
|
||||
uint32_t writeCount;
|
||||
uint32_t renderCount;
|
||||
#endif // TEST_MODE
|
||||
};
|
||||
|
||||
static void UserdataFree(struct Userdata *u);
|
||||
@@ -101,12 +100,53 @@ static ssize_t RenderWrite(struct Userdata *u, pa_memchunk *pchunk)
|
||||
p = pa_memblock_acquire(pchunk->memblock);
|
||||
pa_assert(p);
|
||||
|
||||
#ifdef TEST_MODE
|
||||
while (true) {
|
||||
uint64_t writeLen = 0;
|
||||
|
||||
int32_t ret = u->sinkAdapter->RendererRenderFrame((char *)p + index, (uint64_t)length, &writeLen);
|
||||
if (writeLen > length) {
|
||||
AUDIO_ERR_LOG("Error writeLen > actual bytes. Length: %zu, Written: %" PRIu64 " bytes, %d ret",
|
||||
length, writeLen, ret);
|
||||
count = -1 - count;
|
||||
break;
|
||||
}
|
||||
if (writeLen == 0) {
|
||||
AUDIO_ERR_LOG("Failed to render Length: %zu, Written: %" PRIu64 " bytes, %d ret",
|
||||
length, writeLen, ret);
|
||||
count = -1 - count;
|
||||
break;
|
||||
} else {
|
||||
count += writeLen;
|
||||
index += writeLen;
|
||||
length -= writeLen;
|
||||
if (length <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pa_memblock_release(pchunk->memblock);
|
||||
pa_memblock_unref(pchunk->memblock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t TestModeRenderWrite(struct Userdata *u, pa_memchunk *pchunk)
|
||||
{
|
||||
size_t index, length;
|
||||
ssize_t count = 0;
|
||||
void *p = NULL;
|
||||
|
||||
pa_assert(pchunk);
|
||||
|
||||
index = pchunk->index;
|
||||
length = pchunk->length;
|
||||
p = pa_memblock_acquire(pchunk->memblock);
|
||||
pa_assert(p);
|
||||
|
||||
if (*((int*)p) > 0) {
|
||||
AUDIO_DEBUG_LOG("RenderWrite Write: %{public}d", ++u->writeCount);
|
||||
}
|
||||
AUDIO_DEBUG_LOG("RenderWrite Write renderCount: %{public}d", ++u->renderCount);
|
||||
#endif // TEST_MODE
|
||||
|
||||
while (true) {
|
||||
uint64_t writeLen = 0;
|
||||
@@ -255,6 +295,40 @@ static void ThreadFuncWriteHDI(void *userdata)
|
||||
pa_asyncmsgq_done(u->dq, 0);
|
||||
} while (!quit);
|
||||
}
|
||||
|
||||
static void TestModeThreadFuncWriteHDI(void *userdata)
|
||||
{
|
||||
struct Userdata *u = userdata;
|
||||
pa_assert(u);
|
||||
|
||||
int quit = 0;
|
||||
|
||||
do {
|
||||
int code = 0;
|
||||
pa_memchunk chunk;
|
||||
|
||||
pa_assert_se(pa_asyncmsgq_get(u->dq, NULL, &code, NULL, NULL, &chunk, 1) == 0);
|
||||
|
||||
switch (code) {
|
||||
case HDI_RENDER:
|
||||
if (TestModeRenderWrite(u, &chunk) < 0) {
|
||||
u->bytes_dropped += chunk.length;
|
||||
AUDIO_ERR_LOG("TestModeRenderWrite failed");
|
||||
}
|
||||
if (pa_atomic_load(&u->dflag) == 1) {
|
||||
pa_atomic_sub(&u->dflag, 1);
|
||||
}
|
||||
break;
|
||||
case QUIT:
|
||||
quit = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
pa_asyncmsgq_done(u->dq, 0);
|
||||
} while (!quit);
|
||||
}
|
||||
|
||||
static void SinkUpdateRequestedLatencyCb(pa_sink *s)
|
||||
{
|
||||
struct Userdata *u = NULL;
|
||||
@@ -341,10 +415,8 @@ static int SinkSetStateInIoThreadCb(pa_sink *s, pa_sink_state_t newState,
|
||||
pa_core_exit(u->core, true, 0);
|
||||
} else {
|
||||
u->isHDISinkStarted = true;
|
||||
#ifdef TEST_MODE
|
||||
u->writeCount = 0;
|
||||
u->renderCount = 0;
|
||||
#endif // TEST_MODE
|
||||
AUDIO_INFO_LOG("Successfully restarted HDI renderer");
|
||||
}
|
||||
} else if (PA_SINK_IS_OPENED(s->thread_info.state)) {
|
||||
@@ -520,12 +592,13 @@ pa_sink *PaHdiSinkNew(pa_module *m, pa_modargs *ma, const char *driver)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
u->test_mode_on = false;
|
||||
if (pa_modargs_get_value_boolean(ma, "test_mode_on", &u->test_mode_on) < 0) {
|
||||
AUDIO_INFO_LOG("No test_mode_on arg. Normal mode it is.");
|
||||
}
|
||||
|
||||
pa_atomic_store(&u->dflag, 0);
|
||||
u->dq = pa_asyncmsgq_new(0);
|
||||
#ifdef TEST_MODE
|
||||
u->writeCount = 0;
|
||||
u->renderCount = 0;
|
||||
#endif // TEST_MODE
|
||||
|
||||
u->sink = PaHdiSinkInit(u, ma, driver);
|
||||
if (!u->sink) {
|
||||
@@ -566,10 +639,20 @@ pa_sink *PaHdiSinkNew(pa_module *m, pa_modargs *ma, const char *driver)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hdiThreadName = "write-hdi";
|
||||
if (!(u->thread_hdi = pa_thread_new(hdiThreadName, ThreadFuncWriteHDI, u))) {
|
||||
AUDIO_ERR_LOG("Failed to write-hdi thread.");
|
||||
goto fail;
|
||||
if (u->test_mode_on) {
|
||||
u->writeCount = 0;
|
||||
u->renderCount = 0;
|
||||
hdiThreadName = "test-mode-write-hdi";
|
||||
if (!(u->thread_hdi = pa_thread_new(hdiThreadName, TestModeThreadFuncWriteHDI, u))) {
|
||||
AUDIO_ERR_LOG("Failed to test-mode-write-hdi thread.");
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
hdiThreadName = "write-hdi";
|
||||
if (!(u->thread_hdi = pa_thread_new(hdiThreadName, ThreadFuncWriteHDI, u))) {
|
||||
AUDIO_ERR_LOG("Failed to write-hdi thread.");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
pa_sink_put(u->sink);
|
||||
|
||||
@@ -43,6 +43,7 @@ PA_MODULE_USAGE(
|
||||
"sink_latency=<hdi latency>"
|
||||
"render_in_idle_state<renderer state>"
|
||||
"open_mic_speaker<open mic and speaker>"
|
||||
"test_mode_on<is test mode on>"
|
||||
);
|
||||
|
||||
static const char * const VALID_MODARGS[] = {
|
||||
@@ -60,6 +61,7 @@ static const char * const VALID_MODARGS[] = {
|
||||
"sink_latency",
|
||||
"render_in_idle_state",
|
||||
"open_mic_speaker",
|
||||
"test_mode_on",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
@@ -91,6 +91,7 @@ ohos_prebuilt_etc("audio_policy.rc") {
|
||||
|
||||
config("audio_policy_public_config") {
|
||||
include_dirs = [
|
||||
"//base/startup/syspara_lite/interfaces/innerkits/native/syspara/include",
|
||||
"//drivers/peripheral/audio/interfaces/include",
|
||||
"//foundation/multimedia/audio_framework/services/include",
|
||||
"//foundation/multimedia/audio_framework/services/include/audio_service/client",
|
||||
@@ -190,6 +191,7 @@ ohos_shared_library("audio_policy_service") {
|
||||
"$hdf_uhdf_path/host:libhdf_host",
|
||||
"$hdf_uhdf_path/ipc:libhdf_ipc_adapter",
|
||||
"$hdf_uhdf_path/utils:libhdf_utils",
|
||||
"//base/startup/syspara_lite/interfaces/innerkits/native/syspara:syspara",
|
||||
"//foundation/communication/bluetooth/services/bluetooth/ipc:btipc_static",
|
||||
"//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core",
|
||||
"//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata:distributeddata_inner",
|
||||
|
||||
@@ -129,6 +129,7 @@ private:
|
||||
|
||||
AudioSessionCallback *sessionCallback_;
|
||||
friend class PolicyCallbackImpl;
|
||||
bool testModeOn_ {false};
|
||||
};
|
||||
|
||||
class PolicyCallbackImpl : public AudioServiceAdapterCallback {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "audio_errors.h"
|
||||
#include "audio_log.h"
|
||||
#include "parameter.h"
|
||||
|
||||
#include "audio_adapter_manager.h"
|
||||
|
||||
@@ -27,6 +28,13 @@ namespace OHOS {
|
||||
namespace AudioStandard {
|
||||
bool AudioAdapterManager::Init()
|
||||
{
|
||||
char testMode[10] = {0}; // 10 for system parameter usage
|
||||
auto res = GetParameter("debug.audio_service.testmodeon", "0", testMode, sizeof(testMode));
|
||||
if (res == 1 && testMode[0] == '1') {
|
||||
AUDIO_DEBUG_LOG("testMode on");
|
||||
testModeOn_ = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -306,6 +314,10 @@ std::string AudioAdapterManager::GetModuleArgs(const AudioModuleInfo &audioModul
|
||||
args.append(" sink_latency=");
|
||||
args.append(audioModuleInfo.sinkLatency);
|
||||
}
|
||||
if (testModeOn_) {
|
||||
args.append(" test_mode_on=");
|
||||
args.append("1");
|
||||
}
|
||||
} else if (audioModuleInfo.lib == HDI_SOURCE) {
|
||||
UpdateCommonArgs(audioModuleInfo, args);
|
||||
if (!audioModuleInfo.name.empty()) {
|
||||
|
||||
@@ -1479,14 +1479,12 @@ int32_t AudioServiceClient::RenderPrebuf(uint32_t writeLen)
|
||||
int32_t writeError;
|
||||
StreamBuffer prebufStream;
|
||||
prebufStream.buffer = preBuf_.get();
|
||||
uint32_t extra {0};
|
||||
if (writeLen == 0) {
|
||||
return AUDIO_CLIENT_SUCCESS;
|
||||
} else if (writeLen > diff) {
|
||||
prebufStream.bufferLen = diff;
|
||||
} else {
|
||||
prebufStream.bufferLen = writeLen;
|
||||
extra = diff % writeLen;
|
||||
}
|
||||
|
||||
size_t bytesWritten {0};
|
||||
@@ -1497,12 +1495,12 @@ int32_t AudioServiceClient::RenderPrebuf(uint32_t writeLen)
|
||||
return AUDIO_CLIENT_ERR;
|
||||
}
|
||||
|
||||
if ((diff - bytesWritten) <= 0) {
|
||||
if (static_cast<int32_t>(diff - bytesWritten) <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((diff - bytesWritten) == extra) {
|
||||
prebufStream.bufferLen = extra;
|
||||
if ((diff - bytesWritten) < writeLen) {
|
||||
prebufStream.bufferLen = diff - bytesWritten;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -434,14 +434,12 @@ size_t AudioStream::Write(uint8_t *buffer, size_t buffer_size)
|
||||
stream.bufferLen = buffer_size;
|
||||
isWriteInProgress_ = true;
|
||||
|
||||
#ifdef LATENCY_ACCURACY_TEST
|
||||
if (isFirstWrite_) {
|
||||
if (RenderPrebuf(stream.bufferLen)) {
|
||||
return ERR_WRITE_FAILED;
|
||||
}
|
||||
isFirstWrite_ = false;
|
||||
}
|
||||
#endif // LATENCY_ACCURACY_TEST
|
||||
|
||||
size_t bytesWritten = WriteStream(stream, writeError);
|
||||
isWriteInProgress_ = false;
|
||||
|
||||
@@ -254,7 +254,7 @@ public:
|
||||
if (audioRenderer->GetLatency(latency)) {
|
||||
AUDIO_ERR_LOG("AudioRendererTest: GetLatency failed");
|
||||
break;
|
||||
#if LATENCY_ACCURACY_TEST
|
||||
#ifdef LATENCY_ACCURACY_TEST
|
||||
} else {
|
||||
AUDIO_DEBUG_LOG("GetLatency: %{public}" PRIu64, latency);
|
||||
#endif // LATENCY_ACCURACY_TEST
|
||||
|
||||
Reference in New Issue
Block a user