关闭

查找出现“wait_event_timeout failed for session X”的原因

标签: sessionaudiobuffercodecstructfile
877人阅读 评论(0) 收藏 举报

查找出现“wait_event_timeout failed for session X”的原因

1 Audio相关代码文件

Sound/soc/msm/qdsp6/q6asm.c

Sound/soc/msm/qdsp6/q6adm.c

Sound/soc/msm/qdsp6/q6afe.c

Sound/soc/msm/msm8x60-dai.c

Sound/soc/msm/msm8x60.c

Sound/soc/msm/msm8x60-pcm.c

Sound/soc/msm/snd-soc-lpass-dma.c

Sound/soc/codec/wnc/wnc/wnc_wm8737.c

Arch/arm/mach-msm/qdsp6v2/pcm_out.c

Arch/arm/mach-msm/qdsp6v2/pcm_in.c

Hardware/qcom/media/audio/msm8660/

 

2Arch/arm/mach-msm/qdsp6v2/pcm_out.c

static ssize_t pcm_out_write(struct file *file, const char __user *buf,

                                               size_t count, loff_t *pos)

{

。。。。。。

                   rc = wait_event_timeout(pcm->write_wait,

                                     (atomic_read(&pcm->out_count) ||

                                     atomic_read(&pcm->out_stopped)), 1 * HZ );

                   if (!rc) {

                            pr_err("%s: wait_event_timeout failed for session %d\n",

                                     __func__, pcm->ac->session);

                            goto fail;

                   }

。。。。。。

rc = q6asm_write(pcm->ac, xfer, 0, 0, NO_TIMESTAMP);

。。。。。。

                   atomic_dec(&pcm->out_count);

。。。。。。

}

 

pcm->out_count为目前闲着的buffer个数。向底层每写入1buffer数据,out_count1.

 

3  pcm_out_cb()为回调函数,当底层写完数据后进入,out_count1.

void pcm_out_cb(uint32_t opcode, uint32_t token,

                            uint32_t *payload, void *priv)

{

         struct pcm *pcm = (struct pcm *) priv;

         unsigned long flags;

         spin_lock_irqsave(&pcm->dsp_lock, flags);

         switch (opcode) {

         case ASM_DATA_EVENT_WRITE_DONE:

                   atomic_inc(&pcm->out_count);

                   wake_up(&pcm->write_wait);

                   break;

         default:

                   break;

         }

         spin_unlock_irqrestore(&pcm->dsp_lock, flags);

}

4 atomic_read(&pcm->out_count)等于0时,证明没有闲着的buffer,等1秒钟,仍然没有可以用的buffer,则打印“wait_event_timeout failed for session X”,向上返回0.

若底层有问题,数据传不下去,则会不停的报“wait_event_timeout failed for session X”,若只报一次,证明下次就正常了,所以问题不大。

 

5 HAL层向下写入的过程:

ssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes)

{

if (mStandby) {

        // open driver

        status = ::open("/dev/msm_pcm_out", O_WRONLY/*O_RDWR*/);

    // configuration

        status = ioctl(mFd, AUDIO_GET_CONFIG, &config);

        config.channel_count = AudioSystem::popCount(channels());

        config.sample_rate = sampleRate();

        config.buffer_size = bufferSize();

        config.buffer_count = AUDIO_HW_NUM_OUT_BUF;

        config.codec_type = CODEC_TYPE_PCM;

        status = ioctl(mFd, AUDIO_SET_CONFIG, &config);

        // fill 2 buffers before AUDIO_START

        mStartCount = AUDIO_HW_NUM_OUT_BUF;

        mStandby = false;

    }

    while (count) {

        ssize_t written = ::write(mFd, p, count);

        if (written > 0) {

            count -= written;

            p += written;

        } else {

            if (errno != EAGAIN) return written;

            mRetryCount++;

            LOGW("EAGAIN - retry");

        }

    }

    // start audio after we fill 2 buffers

    if (mStartCount) {

        if (--mStartCount == 0) {

            if(ioctl(mFd, AUDIO_GET_SESSION_ID, &dec_id)) {

                LOGE("AUDIO_GET_SESSION_ID failed*********");

                return 0;

            }

            ioctl(mFd, AUDIO_START, 0);

        }

    }

return bytes;

}

通过ioctl(mFd, AUDIO_SET_CONFIG, &config);将配置传下去。(Buffersize=4800buffercount=2)。

先写入两个buffer,再ioctl(mFd, AUDIO_START, 0);然后再继续写。底层接到AUDIO_START命令后,会设置音量等。猜想这样做可能是为了消除pop音。

 6 音频设备

输入(1)遥控器 usb声卡 pcm1804_mic_tx

      (2)卡拉OK CODEC

输出 HDMI hdmi_stereo_rx

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:24918次
    • 积分:388
    • 等级:
    • 排名:千里之外
    • 原创:12篇
    • 转载:6篇
    • 译文:0篇
    • 评论:2条
    最新评论