当前仓库属于关闭状态,部分功能使用受限,详情请查阅 仓库状态说明
31 Star 196 Fork 199

OpenHarmony-SIG/tpc_c_cplusplus
关闭

[问题咨询]: ALSA找不到声卡驱动

待办的
创建于  
2024-10-10 19:32

问题描述

版本信息:
编辑器:DevEco Studio NEXT Beta1 Version: 5.0.3.810
编辑器内置 SDK:5.0.0
编译工具:commandline-tools-linux-x64-5.0.3.800
alsa: alsa-lib-1.1.3
pjsip: pjproject-2.13.1

我编译了PJSIP和ALSA,编译过程没遇到问题,但是在运行时PJSIP和ALSA都找不到声卡驱动,导致无法呼叫,我不清楚是我编译的问题还是设备的问题,我查了很多资料,都是让我安装ALSA,并重新编译PJSIP,我都编译好了,但是还是没效果,希望可以给些提示,下面是错信息:

pjsua_call.c !Making call with acc #0 to sip:95795403#18872910795@siptest.v-call.cn
pjsua_aud.c  .Set sound device: capture=-1, playback=-2, mode=0, use_default_settings=0
pjsua_aud.c  ..Error retrieving default audio device parameters: Unable to find default audio device (PJMEDIA_EAUD_NODEFDEV) [status=420006]
pjsua_media.c  .Call 0: deinitializing media..
    call.cpp  pjsua_call_make_call(acc.getId(), &pj_dst_uri, param.p_opt, this, param.p_msg_data, &id) error: Unable to find default audio device (PJMEDIA_EAUD_NODEFDEV) (status=420006) [../src/pjsua2/call.cpp:701]

在注册发起时,可以看到PJSIP确实已经使用了ALSA,但是依然找不到设备“ALSA driver found 0 devices”

sip_endpoint.c  .Module "mod-100rel" registered
sip_endpoint.c  .Module "mod-pjsua" registered
sip_endpoint.c  .Module "mod-invite" registered
    alsa_dev.c  ..ALSA driver found 0 devices
    alsa_dev.c  ..ALSA initialized
         pjlib  ..select() I/O Queue created (0x5b0c387c28)
sip_endpoint.c  .Module "mod-evsub" registered

我在编译ALSA时使用的是默认设备路径,是不是跟这个有关系?

checking for ALSA device file directory... /dev/snd/
checking for aload* device file directory... /dev/

评论 (22)

击鼓卖糖 创建了任务 8个月前
击鼓卖糖 添加了
 
question
标签
8个月前
击鼓卖糖 修改了描述 8个月前
击鼓卖糖 修改了描述 8个月前
展开全部操作日志

OH应用层不支持alsa,应用无法调用alsa的接口的。音频模块OH当前有ohaudio/opensl模块,建议用户自行适配OH的ohaudio。OHAUDIO介绍文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/using-ohaudio-for-playback-V5.OHAUDIO的demo实例:https://gitee.com/harmonyos_samples/audio-native

好的,感谢! 我看第三方库里有alsa-lib,我还以为支持呢

我没看太懂你的 AudioRendererOnWriteData 方法里是要干嘛?注册一个pj_thread线程?我的实现方式是在 AudioRendererOnWriteData 方法这种从缓存队列中读取buffer数据,并填充到 void *buffer 里,实现音频输出,下面是我的实现

int32_t AudioRendererOnWriteData(OH_AudioRenderer *renderer, void *userData, void *buffer, int32_t bufferLen) {
    (void) renderer;
    (void) userData;
    renderMtx.lock();
    uint8_t *dest = (uint8_t *)buffer;
    size_t index = 0;
    size_t len = bufferLen > renderQueue.size() ? renderQueue.size() : bufferLen;
    while (!renderQueue.empty() && index < len) {
        dest[index++] = renderQueue.front();
        renderQueue.pop();
    }
    renderMtx.unlock();
    return 0;
}

您好,非常感谢回复,想实现的目标是在鸿蒙next版本的虚拟机上可以使用pjsip来实现voip业务。
开始,也遇到了找不到音频设备,然后按照上面给的建议“需用户自行适配OH的ohaudio”,在pjsip里面根据ohaudio demo逻辑在pjsip里添加ohaudio模块,并重新编译;
随后,使用dev创建c++工程并使用编译后的库文件,在调用makecall后出现

“LastFatalMessage:Assertion failed: !"Calling pjlib from unknown/external thread. You must " "register external threads with pj_thread_register() " "before calling any pjlib functions." (../src/pj/os_core_unix.c: pj_thread_this: 844)”,
Fault thread info:
Tid:6719, Name:OS_AudioWriteCB

这样的提示,看到“OS_AudioWriteCB”这样提示, 对应的是OH_AudioRenderer_OnWriteData = AudioRendererOnWriteData,ohaudio play回调函数,然后根据pjsip库提示在AudioRendererOnWriteData回调函数里加入了“pj_thread_register("media", desc, &pthread);}”,并重新编译,但没有效果然后仍有上面的错误提示,回调函数AudioRendererOnWriteData里面不添加任何业务代码,也有上面的错误提示,若设置成OH_AudioRenderer_OnWriteData = NULL则没有上面的错误提示,但媒体数据就不能使用了,所以想问一下对于这样的错误有什么建议

OH_AudioRenderer_Callbacks rendererCallbacks;
rendererCallbacks.OH_AudioRenderer_OnWriteData = AudioRendererOnWriteData;

下面是主要代码


#include <stdbool.h>
#include <ohaudio/native_audiocapturer.h>
#include <ohaudio/native_audiorenderer.h>
#include <ohaudio/native_audiostreambuilder.h>
#include <ohaudio/native_audiostream_base.h>
const int GLOBAL_RESMGR = 0xFF00;
const char *TAG = "[Sample_audio]";
int32_t g_samplingRate = 48000;
int32_t g_channelCount = 1;//2
static OH_AudioCapturer *audioCapturer;
static OH_AudioRenderer *audioRenderer;
static OH_AudioStreamBuilder *builder;
static OH_AudioStreamBuilder *rendererBuilder;
static struct ohaudio_aud_stream *mStream;
#define W_SLBufferQueueItf SLOHBufferQueueItf
#define W_SLBufferQueueState SLOHBufferQueueState
#define W_SL_IID_BUFFERQUEUE SL_IID_OH_BUFFERQUEUE
#define THIS_FILE       "ohaduio_dev.c"
#define DRIVER_NAME     "OhAudio"
#define NUM_BUFFERS 3
static int32_t AudioRendererOnWriteData(OH_AudioRenderer *renderer, void *userData, void *buffer, int32_t bufferLen) {
    try{
        int status;
        if (mStream->play_thread_initialized == 0 || !pj_thread_is_registered())
        {
            pj_bzero(mStream->play_thread_desc, sizeof(pj_thread_desc));
            status = pj_thread_register("ohaudio_play", mStream->play_thread_desc,
                                        &mStream->play_thread);
            mStream->play_thread_initialized = 1;
        }
    }catch(...){
       PJ_LOG(4, (THIS_FILE, "opensl AudioRendererOnWriteData Error ")); 
    }
    return 0;
}
static int32_t AudioCapturerOnReadData(OH_AudioCapturer *capturer, void *userData, void *buffer, int32_t bufferLen) {
     char name[16];
     pthread_getname_np(pthread_self(), name, sizeof(name));
     PJ_LOG(4, (THIS_FILE, "opensl Recorder thread started %s",name)); 
    try{
        int status;
        if (mStream->rec_thread_initialized == 0 || !pj_thread_is_registered())
        {
            // pj_bzero(mStream->rec_thread_desc, sizeof(pj_thread_desc));
            status = pj_thread_register("ohaudio_rec", mStream->rec_thread_desc,
                                        &mStream->rec_thread);
            PJ_UNUSED_ARG(status);  /* Unused for now.. */
            mStream->rec_thread_initialized = 1;
        }
    return 0;
}
/* Init Android audio driver. */
extern "C" pjmedia_aud_dev_factory* pjmedia_ohaudio_factory(pj_pool_factory *pf)
{
    struct ohaudio_aud_factory *f;
    pj_pool_t *pool;
    pool = pj_pool_create(pf, "opensles", 256, 256, NULL);
    f = PJ_POOL_ZALLOC_T(pool, struct ohaudio_aud_factory);
    f->pf = pf;
    f->pool = pool;
    f->base.op = &ohaudio_op;
    return &f->base;
}
/* API: Destroy factory */
static pj_status_t ohaudio_destroy(pjmedia_aud_dev_factory *f)
{
    //录音
    if (audioCapturer) {
        OH_AudioStreamBuilder_Destroy(builder);
        OH_AudioCapturer_Release(audioCapturer);
        audioCapturer = NULL;
        builder = NULL;
    }
    //播放
    if (audioRenderer) {
        OH_AudioStreamBuilder_Destroy(rendererBuilder);
        OH_AudioRenderer_Release(audioRenderer);
        audioRenderer = NULL;
        rendererBuilder = NULL;
    }
    pool = pa->pool;
    pa->pool = NULL;
    pj_pool_release(pool);
    return PJ_SUCCESS;
}
/* API: create stream */
static pj_status_t ohaudio_create_stream(pjmedia_aud_dev_factory *f,
                                        const pjmedia_aud_param *param,
                                        pjmedia_aud_rec_cb rec_cb,
                                        pjmedia_aud_play_cb play_cb,
                                        void *user_data,
                                        pjmedia_aud_stream **p_aud_strm)
{
        if (audioRenderer) {
            OH_AudioRenderer_Release(audioRenderer);
            OH_AudioStreamBuilder_Destroy(rendererBuilder);
            audioRenderer = NULL;
            rendererBuilder = NULL;
        }
        OH_AudioStream_Type type = AUDIOSTREAM_TYPE_RENDERER;
        OH_AudioStreamBuilder_Create(&rendererBuilder, type);
        // set params and callbacks
        OH_AudioStreamBuilder_SetSamplingRate(rendererBuilder, g_samplingRate);//g_samplingRate
        OH_AudioStreamBuilder_SetChannelCount(rendererBuilder, g_channelCount);
        OH_AudioStreamBuilder_SetLatencyMode(rendererBuilder, AUDIOSTREAM_LATENCY_MODE_NORMAL);
        OH_AudioStreamBuilder_SetFrameSizeInCallback(rendererBuilder, 2500);
        OH_AudioStreamBuilder_SetSampleFormat(rendererBuilder, AUDIOSTREAM_SAMPLE_S16LE);
        OH_AudioStreamBuilder_SetEncodingType(rendererBuilder, AUDIOSTREAM_ENCODING_TYPE_RAW);
        // 关键参数,仅OHAudio支持,根据音频用途设置,系统会根据此参数实现音频策略自适应
        OH_AudioStreamBuilder_SetRendererInfo(rendererBuilder, AUDIOSTREAM_USAGE_MOVIE);
        OH_AudioRenderer_Callbacks rendererCallbacks;
        rendererCallbacks.OH_AudioRenderer_OnWriteData = AudioRendererOnWriteData;//AudioRendererOnWriteData
        rendererCallbacks.OH_AudioRenderer_OnStreamEvent = NULL;
        rendererCallbacks.OH_AudioRenderer_OnInterruptEvent = NULL;
        rendererCallbacks.OH_AudioRenderer_OnError = NULL;
        OH_AudioStreamBuilder_SetRendererCallback(rendererBuilder, rendererCallbacks, user_data);
        // create OH_AudioRenderer
        OH_AudioStreamBuilder_GenerateRenderer(rendererBuilder, &audioRenderer);
        if (audioCapturer) {
            OH_AudioCapturer_Release(audioCapturer);
            OH_AudioStreamBuilder_Destroy(builder);
            audioCapturer = NULL;
            builder = NULL;
        }
        OH_AudioStream_Type ohType = AUDIOSTREAM_TYPE_CAPTURER;
        OH_AudioStreamBuilder_Create(&builder, ohType);
        // 2. set params and callbacks
        OH_AudioStreamBuilder_SetSamplingRate(builder, g_samplingRate);//g_samplingRate
        OH_AudioStreamBuilder_SetChannelCount(builder, g_channelCount);
        OH_AudioStreamBuilder_SetLatencyMode(builder, AUDIOSTREAM_LATENCY_MODE_NORMAL);
        OH_AudioCapturer_Callbacks callbacks;
        callbacks.OH_AudioCapturer_OnReadData = AudioCapturerOnReadData;//AudioCapturerOnReadData
        callbacks.OH_AudioCapturer_OnStreamEvent = NULL;
        callbacks.OH_AudioCapturer_OnInterruptEvent = NULL;
        callbacks.OH_AudioCapturer_OnError = NULL;
        OH_AudioStreamBuilder_SetCapturerCallback(builder, callbacks, NULL);
        // 3. create OH_AudioCapturer
        OH_AudioStreamBuilder_GenerateCapturer(builder, &audioCapturer);
    /* Done */
    mStream->base.op = &ohaudio_strm_op;
    *p_aud_strm = &mStream->base;
    return PJ_SUCCESS;
}
/* API: start stream. */
static pj_status_t strm_start(pjmedia_aud_stream *s)
{
    mStream->quit_flag = 0;
    OH_AudioRenderer_Start(audioRenderer);
    OH_AudioCapturer_Start(audioCapturer);
    return PJ_SUCCESS;
}
#endif  /* PJMEDIA_AUDIO_DEV_HAS_OPENSL */

@zhong-luping 您好,按照audio-native demo进行适配

OH_AudioRenderer_Callbacks rendererCallbacks;
rendererCallbacks.OH_AudioRenderer_OnWriteData = AudioRendererOnWriteData;
rendererCallbacks.OH_AudioRenderer_OnError = nullptr;
rendererCallbacks.OH_AudioRenderer_OnInterruptEvent = nullptr;
rendererCallbacks.OH_AudioRenderer_OnStreamEvent = nullptr;
OH_AudioStreamBuilder_SetRendererCallback(rendererBuilder, rendererCallbacks, nullptr);

在虚拟机API12 上运行出现


Reason:Signal:SIGABRT(SI_TKILL)@0x01317b4f0000190d from:6413:20020047
LastFatalMessage:Assertion failed: !"Calling pjlib from unknown/external thread. You must " "register external threads with pj_thread_register() " "before calling any pjlib functions." (../src/pj/os_core_unix.c: pj_thread_this: 844)
Fault thread info:
Tid:6719, Name:OS_AudioWriteCB
#00 pc 00000000000fb05d /system/lib/ld-musl-x86_64.so.1(raise+141)(0256d51fc65a13f36584ed47fd3152bb)
#01 pc 00000000000a2831 /system/lib/ld-musl-x86_64.so.1(abort+17)(0256d51fc65a13f36584ed47fd3152bb)
#02 pc 00000000000a2aec /system/lib/ld-musl-x86_64.so.1(__assert_fail+508)(0256d51fc65a13f36584ed47fd3152bb)
#03 pc 000000000028b4c1 /data/storage/el1/bundle/libs/x86_64/libho_pjsip.so(pj_thread_this+65)(a131d36c44e5c5c1372741c77caa2004d10c4fc4)
Registers:
  rax:0000000000000000 rdx:0000000000000000 rcx:00007ff3e01fc05d rbx:0000000000000000
  rsi:00007ff3be2b8028 rdi:0000000000000002 rbp:00007ff3be2b80c0 rsp:00007ff3be2b8020
  r8:00000000000000d8 r9:00007ff3e0242288 r10:0000000000000008 r11:0000000000000246
  r12:00007ff3c19454e2 r13:00007ff3be2b8150 r14:0000000000000006 r15:000000000000034c rip:00007ff3e01fc05d
Other thread info:

并根据提示修改修改如下,上述的报错依然存在,请问有什么建议吗

static int32_t AudioRendererOnWriteData(OH_AudioRenderer *renderer, void *userData, void *buffer, int32_t bufferLen) {
    pj_thread_desc desc;
    pj_thread_t *pthread = NULL;
        if (!pj_thread_is_registered()) {
        pj_thread_register("media", desc, &pthread);}
}

错误的意思是你在初始化pjsip之前就调用的pjlib的方法,应该是你的调用流程存在问题,检查一下你的Endpoint是否正确初始化,错误中所说的pj_thread_register 方法会在 EndPoint::libCreate 方法调用,并对pjsip进行初始化,大概调用过程是 EndPoint::libCreate => pjsua_create => pj_init => pj_thread_init => pj_thread_register
然后在 pj_thread_register 中使用 rc = pj_thread_local_set(thread_tls_id, thread); 进行线程申请,源码位置 pjproject/pjlib/src/pj/os_core_unix.c 第593行,所以检查一下你 EndPoint::libCreate 是否正确调用

另外PJSIP官网有一个例子,就是初始化Endpoint,并发起注册,你可以参考一下https://docs.pjsip.org/en/latest/pjsua2/hello_world.html#c

Endpoint ep 这样方式创建Endpoint并不能长期持有,应该就是这里有问题,这个ep会在方法执行完后自动释放,使用new创建试试

另外 pj_thread_register 这个方法应该交给pjsip自己内部去调用,目前我还没遇到需要自己去调用pj_thread_register方法的场景,不过我也不一定对,如果你对这个方法的作用非常清楚的话,那当我没说

非常感谢您的回复:
根据建议查了一下,EndPoint::libCreate是正确调用的,并测试自己创建一个线程并在线程调用pj_thread_register正常;但调用ohaudio模块还是会提示上面的错误,请问还有什么建议帮助排查?

代码如下:

try{
    Endpoint ep
    ep.libCreate();
    // Init library
    LogWriter* logger = new MyLogWriter();
    EpConfig ep_cfg ;
    ep_cfg.logConfig.consoleLevel = 4;
    ep_cfg.logConfig.writer =  logger;
    ep_cfg.logConfig.level = 5;
    ep.libInit(ep_cfg );
    // Transport
    TransportConfig tcfg;
    tcfg.port = 5060;
    ep.transportCreate(PJSIP_TRANSPORT_UDP, tcfg);
    // Start library
    ep.libStart();
} catch (Error & err) {
}

创建现场及注册

std::thread t(callFunction);
void callFunction() {
    try{
        pj_thread_desc desc;
        pj_thread_t *pthread = NULL;
        if (!pj_thread_is_registered()) {
            int status = pj_thread_register("makeCall", desc, &pthread);
                if (status == SUCCESS) {
                    OH_LOG_Print(LOG_APP, LOG_FATAL, 0, "Pjsua", "PJSUA2 pj_thread_register");
                }
        }} catch (pj::Error &e) {}
}

返回信息
输入图片说明

您好,非常感谢您的回复,我这边使用oh模拟器调用pjsip也是参考pjsp-apps里面的samples,目前可以正常注册,并按照pjsua2-demo.cpp可以建立语音通话,只不过音频流使用的沙箱音频文件,代码如下,

void MyCall::onCallMediaState(OnCallMediaStateParam &prm)
{
    PJ_UNUSED_ARG(prm);
    CallInfo ci = getInfo();
    AudioMedia aud_med;
    AudioMedia& play_dev_med =
    MyEndpoint::instance().audDevManager().getPlaybackDevMedia();
    if (ci.state == PJSIP_INV_STATE_CONFIRMED ||ci.state ==  PJSIP_INV_STATE_CONNECTING) {
        try {
        // Get the first audio media
        aud_med = getAudioMedia(-1);
    if (!wav_player) {
        wav_player = new AudioMediaPlayer();
        try {
            wav_player->createPlayer(
                "/data/storage/el2/base/haps/entry/files/input.wav", 0);
        } catch (...) {
            std::cout << "Failed opening wav file" << std::endl;
            delete wav_player;
            wav_player = NULL;
        }
    }
    This will connect the wav file to the call audio media
    if (wav_player)
        wav_player->startTransmit(aud_med);
    // And this will connect the call audio media to the sound device/speaker
    aud_med.startTransmit(play_dev_med);
    } catch(...) {
        std::cout << "Failed to get audio media" << std::endl;
        return;}
    }
}

随后,改为使用mic录音作为音频流出现提示需要调用pj_thread_register,从日志看在调用ohaudio 开始录音/播放API会创建线程再进行数据回调,因此,在OH_AudioRenderer_OnWriteData这类回调函数调用pj_thread_register;并测试若在线程使用pjsip内部方法需要pj_thread_register,您那边是在线程里调用pjsip方法也不用去调用pj_thread_register方法吗?

OH_AudioRenderer_Start(audioRenderer);
OH_AudioCapturer_Start(audioCapturer);


[SetCaptureMode]Set mode to CAPTURE_MODE_CALLBACK
[ReadCallbackFunc]Thread start, sessionID :100101
[InitCallbackBuffer]InitCallbackBuffer with duration 20000,

方便问一下,您那边是否按照ohaudio以进行适配pjsip,可以实现在oh内使用mic录音及播放的sip语音通话吗?

你把流存文件是要有录音需求么?我没有存文件,ohaudio的能力可以支持pjsip,我的大概实现流程是如下
1.pjsip 设置空设备,因为pjsip内置的音频设备控制无法直接控制ohaudio
2.pjsip实现一个媒体端口MediaPort的onFrameRequested和onFrameReceived
3.创建出入队列,队列作为pjsip和ohaudio的中间缓冲,因为两侧buffer长度不同,速率也不同,所以需要缓冲
4.ohaudio实现AudioRendererOnWriteData和AudioCapturerOnReadData用来对接两个队列

所以音频的流转过程大概是这样:

  1. 接收音频,pjsip收到音频然后解码,到onFrameReceived,然后加入渲染队列,ohaudio通过AudioRendererOnWriteData消费队列,实现音频播放
  2. 发送音频,ohaudio通过AudioCapturerOnReadData捕获音频,然后加入捕获队列,pjsip通过onFrameRequested消费捕获队列,编码之后发送到远端实现通话

我这边没有涉及到需要创建线程pj线程的场景,所以没用到 pj_thread_register

我也遇到了一些问题,就是连续拨打几通电话之后,使用 OH_AudioRenderer_Release(audioRenderer)释放音频设备会出现释放不掉的情况,没有任何异常日志输入,然后系统会卡住,不能再进行注册或者呼叫,如果你有类似问题的解决思路,还请指点一下

您好,目前这边还没进展到您的那么快,这边适配ohaudio的思路,大概流程如下:
1、这边查看ohaudio 使用的opensles,所以就参考pjmedia模块里面pjmedia-audiodev->opensl_dev.c进行适配,参考https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/replace-opensles-by-ohaudio-V5 opensl 切换ohaudio
2、pjlib模块里面pj 创建config_site.h #define PJMEDIA_AUDIO_DEV_HAS_OPENSL 1,编译库文件再使用
3、目前通过这个方式也可以打通,pjsip与ohaudio中间转换有问题

抱歉,我对opensl不了解,帮不了你

您好,pjsip与ohaudio中间转换,转换有点问题,能帮忙看一下给点思路吗,非常感谢!

//samplingRate 16000 , 16, 1
static int32_t AudioRendererOnWriteData(OH_AudioRenderer *renderer, void *userData, void *buffer, int32_t bufferLen) {
    try{
        int status;
        if (mStream->play_thread_initialized == 0 || !pj_thread_is_registered())
        {
            pj_bzero(mStream->play_thread_desc, sizeof(pj_thread_desc));
            status = pj_thread_register("opensl_play", mStream->play_thread_desc,
                                        &mStream->play_thread);
            mStream->play_thread_initialized = 1;
            PJ_LOG(4, (THIS_FILE, "opensl Player thread started"));
        }
        if (!mStream->quit_flag) {
            pjmedia_frame frame;
            // char * buf;
            frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
            frame.buf = buffer;//buf = mStream->playerBuffer[mStream->playerBufIdx++];
            frame.size = mStream->playerBufferSize;//playerBufferSize :640 
            frame.timestamp.u64 = mStream->play_timestamp.u64;
            frame.bit_info = 0;
            status = (*mStream->play_cb)(mStream->user_data, &frame);//play_cb pjmedia_aud_play_cb
            if (status != PJ_SUCCESS || frame.type != PJMEDIA_FRAME_TYPE_AUDIO){
                pj_bzero(buffer, mStream->playerBufferSize);//mStream->playerBufferSize
            }
            
            mStream->play_timestamp.u64 += mStream->param.samples_per_frame /
                                        mStream->param.channel_count;

            // pj_memcpy(buffer,buf, mStream->playerBufferSize);
            // mStream->playerBufIdx %= NUM_BUFFERS;
        }

    }catch(...){
            PJ_LOG(4, (THIS_FILE, "opensl AudioRendererOnWriteData Error ")); 
    }
    return 0;
}
static int32_t AudioCapturerOnReadData(OH_AudioCapturer *capturer, void *userData, void *buffer, int32_t bufferLen) {
    try{
        int status;
        if (mStream->rec_thread_initialized == 0 || !pj_thread_is_registered())
        {
            // pj_bzero(mStream->rec_thread_desc, sizeof(pj_thread_desc));
            status = pj_thread_register("opensl_rec", mStream->rec_thread_desc,
                                        &mStream->rec_thread);
            PJ_UNUSED_ARG(status);  /* Unused for now.. */
            mStream->rec_thread_initialized = 1;
        }
        if (!mStream->quit_flag) {
            pjmedia_frame frame;
            char *buf;
            // mStream->recordBufferSize = bufferLen;
            frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
            frame.buf = buffer;//buf = mStream->recordBuffer[mStream->recordBufIdx++];
            frame.size = mStream->recordBufferSize;
            frame.timestamp.u64 = mStream->rec_timestamp.u64;
            frame.bit_info = 0;
            status = (*mStream->rec_cb)(mStream->user_data, &frame);
            mStream->rec_timestamp.u64 += mStream->param.samples_per_frame /
                                        mStream->param.channel_count;
            /* And now enqueue next buffer */
            // result = (*bq)->Enqueue(bq, buf, stream->recordBufferSize);
            // if (result != SL_RESULT_SUCCESS) {
            //     PJ_LOG(3, (THIS_FILE, "Unable to enqueue next record buffer !!! %d",
            //                           result));
            // }
            // pj_memcpy(buf,buffer, mStream->recordBufferSize);
            mStream->recordBufIdx %= NUM_BUFFERS;
        }
    }catch(...){
        PJ_LOG(4, (THIS_FILE, "opensl Recorder Error ")); 

    }
    return 0;
}

您好,我这边opensl的适配也是参考pjsip里面的opensl_dev.c代码,您上面适配思路,有参考的文档吗,对pjsip实现一个媒体端口MediaPort不了解,想根据您的思路试试

https://github.com/pjsip/pjproject/blob/master/pjsip-apps/src/samples/pjsua2_demo.cpp

你可以看看这个官方的例子,第53行就是实现的媒体端口,思路就是我之前说的使用队列做中间缓冲队列连接ohaudio和pjsip的媒体端扣

您好,当前pjproject版本是2.13.1, pjsua2_demo.cpp使用的AudioMediaPort,是需要把pjproject-2.13.1工程里的pjsip模块单独更新,还是整个pjproject都需要更新?

我用的 pjproject-2.14.1

您好,您那边是否也对oh视频通话进行适配了,有什么思路还请指点一下,非常感谢!

暂时没有计划,可能后面会做吧

登录 后才可以发表评论

状态
负责人
项目
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
预计工期 (小时)
开始日期   -   截止日期
-
置顶选项
优先级
里程碑
分支
参与者(3)
8708331 zhong luping 1636340013 击鼓卖糖-dyinfalse lixiansheng-AheadTime
1
https://gitee.com/openharmony-sig/tpc_c_cplusplus.git
git@gitee.com:openharmony-sig/tpc_c_cplusplus.git
openharmony-sig
tpc_c_cplusplus
tpc_c_cplusplus

搜索帮助